aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-07-25 02:13:56 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 05:21:00 -0400
commit55c16a70041ba55e235c5944dccb9c1de0dd3ca6 (patch)
treee48c1d9943fc52329cae1656ca59d24751dd9b98
parentba2da2f8d61a9d2e24754c6311a4ab6a5e70060a (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.c3
-rw-r--r--drivers/ide/ide-dma.c2
-rw-r--r--drivers/ide/ide-io.c3
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide-taskfile.c18
-rw-r--r--drivers/ide/mips/au1xxx-ide.c2
-rw-r--r--drivers/ide/pci/sgiioc4.c3
-rw-r--r--drivers/ide/ppc/pmac.c2
-rw-r--r--include/linux/ide.h2
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
852EXPORT_SYMBOL_GPL(ide_init_sg_cmd); 853EXPORT_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
368static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) 376static 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 */