IDE: sg chaining support
authorJens Axboe <jens.axboe@oracle.com>
Wed, 25 Jul 2007 06:13:56 +0000 (08:13 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 16 Oct 2007 09:21:00 +0000 (11:21 +0200)
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
drivers/ide/cris/ide-cris.c
drivers/ide/ide-dma.c
drivers/ide/ide-io.c
drivers/ide/ide-probe.c
drivers/ide/ide-taskfile.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/pci/sgiioc4.c
drivers/ide/ppc/pmac.c
include/linux/ide.h

index 2b4d2a0ae5c26e1d7bf7f42b1630b0c36a6332ab..c306c9f534ab6600e665669f44d2bc05377ad2f2 100644 (file)
@@ -939,7 +939,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
                /* group sequential buffers into one large buffer */
                addr = page_to_phys(sg->page) + sg->offset;
                size = sg_dma_len(sg);
-               while (sg++, --i) {
+               while (--i) {
+                       sg = sg_next(sg);
                        if ((addr + size) != page_to_phys(sg->page) + sg->offset)
                                break;
                        size += sg_dma_len(sg);
index b453211ee0fc1364cebe09be3bd0296bf6500207..a4cbbbaccde9d7bea55537d6b8da755996751ea0 100644 (file)
@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
                        }
                }
 
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
index f36ff5962af68a0acdbb7bca742a1b6bfc212097..04273d3c147c09ecead03f5e9315740a530d1d03 100644 (file)
@@ -846,7 +846,8 @@ 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;
+       hwif->cursg_ofs = 0;
+       hwif->cursg = NULL;
 }
 
 EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
index d1011712601c9a01913d143200c615d713d4bae2..34b1fb65bc79e3c5d396721b74859715474642d7 100644 (file)
@@ -1349,7 +1349,7 @@ static int hwif_init(ide_hwif_t *hwif)
        if (!hwif->sg_max_nents)
                hwif->sg_max_nents = PRD_ENTRIES;
 
-       hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+       hwif->sg_table = kzalloc(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);
index aa06dafb74acb09dd4383e5a3c7421dcc13db2b7..2a3c8d498343ff417f398d1fb4b93e8678dbf82f 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/bitops.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct scatterlist *sg = hwif->sg_table;
+       struct scatterlist *cursg = hwif->cursg;
        struct page *page;
 #ifdef CONFIG_HIGHMEM
        unsigned long flags;
@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
        unsigned int offset;
        u8 *buf;
 
-       page = sg[hwif->cursg].page;
-       offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE;
+       cursg = hwif->cursg;
+       if (!cursg) {
+               cursg = sg;
+               hwif->cursg = sg;
+       }
+
+       page = cursg->page;
+       offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
        /* get the current page and offset */
        page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
        hwif->nleft--;
        hwif->cursg_ofs++;
 
-       if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) {
-               hwif->cursg++;
+       if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
+               hwif->cursg = sg_next(hwif->cursg);
                hwif->cursg_ofs = 0;
        }
 
@@ -367,6 +375,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
 
 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
+       HWIF(drive)->cursg = NULL;
+
        if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
                ide_task_t *task = rq->special;
 
index aebde49365d16a68b28fdce811a95052c3262e1b..892d08f61dc0b64f3200b7c8ba39c2b9bbc8fbc8 100644 (file)
@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
                        cur_addr += tc;
                        cur_len -= tc;
                }
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
index 85ffaaa39b1b87eecc84e1f87a4d8911fdfa2dfd..c74fef6bbc916058cf0dc56f1c78200d59d7401a 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
+#include <linux/scatterlist.h>
 #include <linux/ioc4.h>
 #include <asm/io.h>
 
@@ -537,7 +538,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
                        }
                }
 
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
index 7d8873839e2103d8af49c7dd0fe73260c23af88a..9e86406bf44b7c6ebfc700cdbc16dc358dd50bc0 100644 (file)
@@ -1539,7 +1539,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
                        cur_len -= tc;
                        ++table;
                }
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
index 234fa3df24f6a9014f9fb053c076e1787d326da6..30a1931466a615983ce504417a91bdc481dc79e9 100644 (file)
@@ -772,7 +772,7 @@ typedef struct hwif_s {
 
        unsigned int nsect;
        unsigned int nleft;
-       unsigned int cursg;
+       struct scatterlist *cursg;
        unsigned int cursg_ofs;
 
        int             rqsize;         /* max sectors per request */