Skip to contentSkip to conversation

ide-2.6 update

PATCH New Bartlomiej Zolnierkiewicz 1 participant 1 message Oct 20, 2004

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ide-2.6 update

Hi,

Some more syncing with -mm:
* convert PIO code to use scatterlists
* unify ide-disk.c and ide-taskfile.c PIO code

Andrew, ide-dev will break again for a short moment. I'll send you mail when it is fixed.

Linus, please do a

	bk pull bk://bart.bkbits.net/ide-2.6

This will update the following files:

 Documentation/block/biodoc.txt   |    3 
 arch/cris/arch-v10/drivers/ide.c |    4 
 drivers/ide/arm/icside.c         |   27 ---
 drivers/ide/ide-disk.c           |  273 ++++-----------------------------------
 drivers/ide/ide-dma.c            |   15 --
 drivers/ide/ide-io.c             |   37 +++++
 drivers/ide/ide-probe.c          |   10 +
 drivers/ide/ide-taskfile.c       |  149 +++++++++------------
 drivers/ide/ide.c                |    3 
 drivers/ide/pci/sgiioc4.c        |   10 -
 drivers/ide/ppc/pmac.c           |   70 ++++------
 include/linux/ide.h              |   59 +-------
 12 files changed, 194 insertions(+), 466 deletions(-)

through these ChangeSets:

<bzolnier@trik.(none)> (04/10/20 1.2016)
[ide] unify PIO code

Use PIO code from ide-taskfile.c in ide-disk.c so:
* drive status is checked after PIO read
* request is failed if invalid data phase is detected during PIO write

<bzolnier@trik.(none)> (04/10/20 1.2015)
[ide] ide-disk: unify PIO write/multiwrite code

Merge multwrite_intr() into write_intr().

The only change in functionality is that rq->errors is now also cleared for multiwrite PIO (if there is no error).

<bzolnier@trik.(none)> (04/10/20 1.2014)
[ide] sg PIO for fs requests

Convert CONFIG_IDE_TASKFILE_IO=n code
to use scatterlists for PIO transfers.

Fixes longstanding 'data integrity on error'
issue and makes barriers work with PIO.

<bzolnier@trik.(none)> (04/10/20 1.2013)
[ide] sg PIO for taskfile requests

Use scatterlists for taskfile based PIO transfers instead of directly walking rq->[bio,cbio] lists.

If CONFIG_IDE_TASKFILE_IO is defined
this code will be used for fs requests.

ide_pio_sector() is based on ata_pio_sector()
from libata-core.c so kudos to Jeff.

<bzolnier@trik.(none)> (04/10/20 1.2012)
[ide] always allocate hwif->sg_table

Allocate hwif->sg_table in hwif_init() so it can also be used for PIO.

<bzolnier@trik.(none)> (04/10/20 1.2011)
[ide] pmac: use more ide_hwif_t fields

Use dmatable_dma, sg_table, sg_nents and sg_dma_direction fields of ide_hwif_t and remove their equivalents from pmac_ide_hwif_t.

Documentation/block/biodoc.txt +1 -2
diff -Nru a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
@@ -1172,8 +1172,7 @@
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
 (Sec 1.1, (ii) ) it needs to use __bio_kmap_atomic and bio_kmap_irq to
-temporarily map a bio into the virtual address space. See how IDE handles
-this with ide_map_buffer.
+temporarily map a bio into the virtual address space.
 
 
 8. Prior/Related/Impacted patches
arch/cris/arch-v10/drivers/ide.c +3 -1
diff -Nru a/arch/cris/arch-v10/drivers/ide.c b/arch/cris/arch-v10/drivers/ide.c
@@ -297,8 +297,10 @@
 	}
 
 	/* set up the Etrax DMA descriptors */
-	if (e100_ide_build_dmatable(drive))
+	if (e100_ide_build_dmatable(drive)) {
+		ide_map_sg(drive, rq);
 		return 1;
+	}
 
 	return 0;
 }
drivers/ide/arm/icside.c +1 -26
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
@@ -206,8 +206,6 @@
  * here, but we rely on the main IDE driver spotting that both
  * interfaces use the same IRQ, which should guarantee this.
  */
-#define NR_ENTRIES 256
-#define TABLE_SIZE (NR_ENTRIES * 8)
 
 static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
 {
@@ -527,7 +525,7 @@
 	return 1;
 }
 
-static int icside_dma_init(ide_hwif_t *hwif)
+static void icside_dma_init(ide_hwif_t *hwif)
 {
 	int autodma = 0;
 
@@ -537,11 +535,6 @@
 
 	printk("    %s: SG-DMA", hwif->name);
 
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES,
-				 GFP_KERNEL);
-	if (!hwif->sg_table)
-		goto failed;
-
 	hwif->atapi_dma		= 1;
 	hwif->mwdma_mask	= 7; /* MW0..2 */
 	hwif->swdma_mask	= 7; /* SW0..2 */
@@ -569,24 +562,9 @@
 	hwif->drives[1].autodma = hwif->autodma;
 
 	printk(" capable%s\n", hwif->autodma ? ", auto-enable" : "");
-
-	return 1;
-
-failed:
-	printk(" disabled, unable to allocate DMA table\n");
-	return 0;
-}
-
-static void icside_dma_exit(ide_hwif_t *hwif)
-{
-	if (hwif->sg_table) {
-		kfree(hwif->sg_table);
-		hwif->sg_table = NULL;
-	}
 }
 #else
 #define icside_dma_init(hwif)	(0)
-#define icside_dma_exit(hwif)	do { } while (0)
 #endif
 
 static ide_hwif_t *icside_find_hwif(unsigned long dataport)
@@ -811,9 +789,6 @@
 
 	case ICS_TYPE_V6:
 		/* FIXME: tell IDE to stop using the interface */
-		icside_dma_exit(state->hwif[1]);
-		icside_dma_exit(state->hwif[0]);
-
 		if (ec->dma != NO_DMA)
 			free_dma(ec->dma);
 
drivers/ide/ide-disk.c +29 -244

311 lines not on this page · raw message

drivers/ide/ide-dma.c +5 -10
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
@@ -610,8 +610,10 @@
 		reading = 1 << 3;
 
 	/* fall back to pio! */
-	if (!ide_build_dmatable(drive, rq))
+	if (!ide_build_dmatable(drive, rq)) {
+		ide_map_sg(drive, rq);
 		return 1;
+	}
 
 	/* PRD table */
 	hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
@@ -810,10 +812,6 @@
 				    hwif->dmatable_dma);
 		hwif->dmatable_cpu = NULL;
 	}
-	if (hwif->sg_table) {
-		kfree(hwif->sg_table);
-		hwif->sg_table = NULL;
-	}
 	return 1;
 }
 
@@ -846,15 +844,12 @@
 	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
 						  PRD_ENTRIES * PRD_BYTES,
 						  &hwif->dmatable_dma);
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
-				GFP_KERNEL);
 
-	if ((hwif->dmatable_cpu) && (hwif->sg_table))
+	if (hwif->dmatable_cpu)
 		return 0;
 
-	printk(KERN_ERR "%s: -- Error, unable to allocate%s%s table(s).\n",
+	printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
 		(hwif->dmatable_cpu == NULL) ? " CPU" : "",
-		(hwif->sg_table == NULL) ?  " SG DMA" : " DMA",
 		hwif->cds->name);
 
 	ide_release_dma_engine(hwif);
drivers/ide/ide-io.c +37 -0
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
@@ -47,6 +47,7 @@
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/kmod.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -674,6 +675,31 @@
 
 EXPORT_SYMBOL(do_special);
 
+void ide_map_sg(ide_drive_t *drive, struct request *rq)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist *sg = hwif->sg_table;
+
+	if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
+		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
+	} else {
+		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
+		hwif->sg_nents = 1;
+	}
+}
+
+EXPORT_SYMBOL_GPL(ide_map_sg);
+
+void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+{
+	ide_hwif_t *hwif = drive->hwif;
+
+	hwif->nsect = hwif->nleft = rq->nr_sectors;
+	hwif->cursg = hwif->cursg_ofs = 0;
+}
+
+EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
+
 /**
  *	execute_drive_command	-	issue special drive command
  *	@drive: the drive to issue th command on
@@ -696,6 +722,17 @@
 			goto done;
 
 		hwif->data_phase = args->data_phase;
+
+		switch (hwif->data_phase) {
+		case TASKFILE_MULTI_OUT:
+		case TASKFILE_OUT:
+		case TASKFILE_MULTI_IN:
+		case TASKFILE_IN:
+			ide_init_sg_cmd(drive, rq);
+			ide_map_sg(drive, rq);
+		default:
+			break;
+		}
 
 		if (args->tf_out_flags.all != 0) 
 			return flagged_taskfile(drive, args);
drivers/ide/ide-probe.c +10 -0
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
@@ -1246,6 +1246,16 @@
 	if (register_blkdev(hwif->major, hwif->name))
 		return 0;
 
+	if (!hwif->sg_max_nents)
+		hwif->sg_max_nents = PRD_ENTRIES;
+
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+				 GFP_KERNEL);
+	if (!hwif->sg_table) {
+		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
+		goto out;
+	}
+
 	if (alloc_disks(hwif) < 0)
 		goto out;
 	
drivers/ide/ide-taskfile.c +65 -84

225 lines not on this page · raw message

drivers/ide/ide.c +3 -0
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
@@ -712,6 +712,8 @@
 	hwif->INSW			= tmp_hwif->INSW;
 	hwif->INSL			= tmp_hwif->INSL;
 
+	hwif->sg_max_nents		= tmp_hwif->sg_max_nents;
+
 	hwif->mmio			= tmp_hwif->mmio;
 	hwif->rqsize			= tmp_hwif->rqsize;
 	hwif->no_lba48			= tmp_hwif->no_lba48;
@@ -900,6 +902,7 @@
 		hwif->drives[i].disk = NULL;
 		put_disk(disk);
 	}
+	kfree(hwif->sg_table);
 	unregister_blkdev(hwif->major, hwif->name);
 	spin_lock_irq(&ide_lock);
 
drivers/ide/pci/sgiioc4.c +2 -8
diff -Nru a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
@@ -404,11 +404,7 @@
 	if (!hwif->dmatable_cpu)
 		goto dma_alloc_failure;
 
-	hwif->sg_table =
-	    kmalloc(sizeof (struct scatterlist) * IOC4_PRD_ENTRIES, GFP_KERNEL);
-
-	if (!hwif->sg_table)
-		goto dma_sgalloc_failure;
+	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
 	hwif->dma_base2 = (unsigned long)
 		pci_alloc_consistent(hwif->pci_dev,
@@ -421,9 +417,6 @@
 	return;
 
 dma_base2alloc_failure:
-	kfree(hwif->sg_table);
-
-dma_sgalloc_failure:
 	pci_free_consistent(hwif->pci_dev,
 			    IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
 			    hwif->dmatable_cpu, hwif->dmatable_dma);
@@ -584,6 +577,7 @@
 
 	if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
 		/* try PIO instead of DMA */
+		ide_map_sg(drive, rq);
 		return 1;
 	}
 
drivers/ide/ppc/pmac.c +29 -41

170 lines not on this page · raw message

include/linux/ide.h +0 -16
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
@@ -789,27 +789,6 @@
 	struct gendisk *disk;
 } ide_drive_t;
 
-/*
- * mapping stuff, prepare for highmem...
- * 
- * temporarily mapping a (possible) highmem bio for PIO transfer
- */
-#ifndef CONFIG_IDE_TASKFILE_IO
-
-#define ide_rq_offset(rq) \
-	(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
-
-static inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
-{
-	return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
-}
-
-static inline void ide_unmap_buffer(struct request *rq, char *buffer,

unsigned long *flags)
-{
- bio_kunmap_irq(buffer, flags);
-}
-#endif /* !CONFIG_IDE_TASKFILE_IO */
-

 #define IDE_CHIPSET_PCI_MASK	\
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))

#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
@@ -920,12 +899,18 @@
dma_addr_t dmatable_dma;
/* Scatter-gather list used to build the above */ struct scatterlist *sg_table;
+ int sg_max_nents; /* Maximum number of entries in it */
int sg_nents; /* Current number of entries in it */
int sg_dma_direction; /* dma transfer direction */

/* data phase of the active command (currently only valid for PIO/DMA) */
int data_phase;

+ unsigned int nsect;
+ unsigned int nleft;
+ unsigned int cursg;
+ unsigned int cursg_ofs;
+
int mmio; /* hosts iomio (0) or custom (2) select */
int rqsize; /* max sectors per request */
int irq; /* our irq number */
@@ -1369,35 +1354,6 @@
extern void taskfile_input_data(ide_drive_t *, void *, u32); extern void taskfile_output_data(ide_drive_t *, void *, u32);

-#define IDE_PIO_IN 0
-#define IDE_PIO_OUT 1
-
-static inline void __task_sectors(ide_drive_t *drive, char *buf,
- unsigned nsect, unsigned rw)
-{
- /*
- * IRQ can happen instantly after reading/writing
- * last sector of the datablock.
- */
- if (rw == IDE_PIO_OUT)
- taskfile_output_data(drive, buf, nsect * SECTOR_WORDS);
- else
- taskfile_input_data(drive, buf, nsect * SECTOR_WORDS);
-}
-
-#ifdef CONFIG_IDE_TASKFILE_IO
-static inline void task_bio_sectors(ide_drive_t *drive, struct request *rq,
- unsigned nsect, unsigned rw)
-{
- unsigned long flags;
- char *buf = rq_map_buffer(rq, &flags);
-
- process_that_request_first(rq, nsect);
- __task_sectors(drive, buf, nsect, rw);
- rq_unmap_buffer(buf, &flags);
-}
-#endif /* CONFIG_IDE_TASKFILE_IO */
-
extern int drive_is_ready(ide_drive_t *);
extern int wait_for_ready(ide_drive_t *, int /* timeout */);

@@ -1527,6 +1483,9 @@

extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *,
ide_pci_device_t *);
+
+void ide_map_sg(ide_drive_t *, struct request *);
+void ide_init_sg_cmd(ide_drive_t *, struct request *);

#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1