ide-2.6 update
Subsystems (4)
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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