diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-07-25 02:13:56 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2007-10-16 05:21:00 -0400 |
commit | 55c16a70041ba55e235c5944dccb9c1de0dd3ca6 (patch) | |
tree | e48c1d9943fc52329cae1656ca59d24751dd9b98 | |
parent | ba2da2f8d61a9d2e24754c6311a4ab6a5e70060a (diff) |
IDE: sg chaining support
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | drivers/ide/cris/ide-cris.c | 3 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 3 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 18 | ||||
-rw-r--r-- | drivers/ide/mips/au1xxx-ide.c | 2 | ||||
-rw-r--r-- | drivers/ide/pci/sgiioc4.c | 3 | ||||
-rw-r--r-- | drivers/ide/ppc/pmac.c | 2 | ||||
-rw-r--r-- | include/linux/ide.h | 2 |
9 files changed, 25 insertions, 12 deletions
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 2b4d2a0ae5c2..c306c9f534ab 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
@@ -939,7 +939,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive) | |||
939 | /* group sequential buffers into one large buffer */ | 939 | /* group sequential buffers into one large buffer */ |
940 | addr = page_to_phys(sg->page) + sg->offset; | 940 | addr = page_to_phys(sg->page) + sg->offset; |
941 | size = sg_dma_len(sg); | 941 | size = sg_dma_len(sg); |
942 | while (sg++, --i) { | 942 | while (--i) { |
943 | sg = sg_next(sg); | ||
943 | if ((addr + size) != page_to_phys(sg->page) + sg->offset) | 944 | if ((addr + size) != page_to_phys(sg->page) + sg->offset) |
944 | break; | 945 | break; |
945 | size += sg_dma_len(sg); | 946 | size += sg_dma_len(sg); |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index b453211ee0fc..a4cbbbaccde9 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) | |||
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
283 | sg++; | 283 | sg = sg_next(sg); |
284 | i--; | 284 | i--; |
285 | } | 285 | } |
286 | 286 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index f36ff5962af6..04273d3c147c 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -846,7 +846,8 @@ void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq) | |||
846 | ide_hwif_t *hwif = drive->hwif; | 846 | ide_hwif_t *hwif = drive->hwif; |
847 | 847 | ||
848 | hwif->nsect = hwif->nleft = rq->nr_sectors; | 848 | hwif->nsect = hwif->nleft = rq->nr_sectors; |
849 | hwif->cursg = hwif->cursg_ofs = 0; | 849 | hwif->cursg_ofs = 0; |
850 | hwif->cursg = NULL; | ||
850 | } | 851 | } |
851 | 852 | ||
852 | EXPORT_SYMBOL_GPL(ide_init_sg_cmd); | 853 | EXPORT_SYMBOL_GPL(ide_init_sg_cmd); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index d1011712601c..34b1fb65bc79 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1349,7 +1349,7 @@ static int hwif_init(ide_hwif_t *hwif) | |||
1349 | if (!hwif->sg_max_nents) | 1349 | if (!hwif->sg_max_nents) |
1350 | hwif->sg_max_nents = PRD_ENTRIES; | 1350 | hwif->sg_max_nents = PRD_ENTRIES; |
1351 | 1351 | ||
1352 | hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents, | 1352 | hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents, |
1353 | GFP_KERNEL); | 1353 | GFP_KERNEL); |
1354 | if (!hwif->sg_table) { | 1354 | if (!hwif->sg_table) { |
1355 | printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); | 1355 | printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index aa06dafb74ac..2a3c8d498343 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/hdreg.h> | 45 | #include <linux/hdreg.h> |
46 | #include <linux/ide.h> | 46 | #include <linux/ide.h> |
47 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
48 | #include <linux/scatterlist.h> | ||
48 | 49 | ||
49 | #include <asm/byteorder.h> | 50 | #include <asm/byteorder.h> |
50 | #include <asm/irq.h> | 51 | #include <asm/irq.h> |
@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
263 | { | 264 | { |
264 | ide_hwif_t *hwif = drive->hwif; | 265 | ide_hwif_t *hwif = drive->hwif; |
265 | struct scatterlist *sg = hwif->sg_table; | 266 | struct scatterlist *sg = hwif->sg_table; |
267 | struct scatterlist *cursg = hwif->cursg; | ||
266 | struct page *page; | 268 | struct page *page; |
267 | #ifdef CONFIG_HIGHMEM | 269 | #ifdef CONFIG_HIGHMEM |
268 | unsigned long flags; | 270 | unsigned long flags; |
@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
270 | unsigned int offset; | 272 | unsigned int offset; |
271 | u8 *buf; | 273 | u8 *buf; |
272 | 274 | ||
273 | page = sg[hwif->cursg].page; | 275 | cursg = hwif->cursg; |
274 | offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE; | 276 | if (!cursg) { |
277 | cursg = sg; | ||
278 | hwif->cursg = sg; | ||
279 | } | ||
280 | |||
281 | page = cursg->page; | ||
282 | offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE; | ||
275 | 283 | ||
276 | /* get the current page and offset */ | 284 | /* get the current page and offset */ |
277 | page = nth_page(page, (offset >> PAGE_SHIFT)); | 285 | page = nth_page(page, (offset >> PAGE_SHIFT)); |
@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
285 | hwif->nleft--; | 293 | hwif->nleft--; |
286 | hwif->cursg_ofs++; | 294 | hwif->cursg_ofs++; |
287 | 295 | ||
288 | if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) { | 296 | if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) { |
289 | hwif->cursg++; | 297 | hwif->cursg = sg_next(hwif->cursg); |
290 | hwif->cursg_ofs = 0; | 298 | hwif->cursg_ofs = 0; |
291 | } | 299 | } |
292 | 300 | ||
@@ -367,6 +375,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | |||
367 | 375 | ||
368 | static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | 376 | static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) |
369 | { | 377 | { |
378 | HWIF(drive)->cursg = NULL; | ||
379 | |||
370 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 380 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
371 | ide_task_t *task = rq->special; | 381 | ide_task_t *task = rq->special; |
372 | 382 | ||
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index aebde49365d1..892d08f61dc0 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c | |||
@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive) | |||
296 | cur_addr += tc; | 296 | cur_addr += tc; |
297 | cur_len -= tc; | 297 | cur_len -= tc; |
298 | } | 298 | } |
299 | sg++; | 299 | sg = sg_next(sg); |
300 | i--; | 300 | i--; |
301 | } | 301 | } |
302 | 302 | ||
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 85ffaaa39b1b..c74fef6bbc91 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
32 | #include <linux/scatterlist.h> | ||
32 | #include <linux/ioc4.h> | 33 | #include <linux/ioc4.h> |
33 | #include <asm/io.h> | 34 | #include <asm/io.h> |
34 | 35 | ||
@@ -537,7 +538,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) | |||
537 | } | 538 | } |
538 | } | 539 | } |
539 | 540 | ||
540 | sg++; | 541 | sg = sg_next(sg); |
541 | i--; | 542 | i--; |
542 | } | 543 | } |
543 | 544 | ||
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 7d8873839e21..9e86406bf44b 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1539,7 +1539,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) | |||
1539 | cur_len -= tc; | 1539 | cur_len -= tc; |
1540 | ++table; | 1540 | ++table; |
1541 | } | 1541 | } |
1542 | sg++; | 1542 | sg = sg_next(sg); |
1543 | i--; | 1543 | i--; |
1544 | } | 1544 | } |
1545 | 1545 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 234fa3df24f6..30a1931466a6 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -772,7 +772,7 @@ typedef struct hwif_s { | |||
772 | 772 | ||
773 | unsigned int nsect; | 773 | unsigned int nsect; |
774 | unsigned int nleft; | 774 | unsigned int nleft; |
775 | unsigned int cursg; | 775 | struct scatterlist *cursg; |
776 | unsigned int cursg_ofs; | 776 | unsigned int cursg_ofs; |
777 | 777 | ||
778 | int rqsize; /* max sectors per request */ | 778 | int rqsize; /* max sectors per request */ |