Commit 55c16a70 authored by Jens Axboe's avatar Jens Axboe

IDE: sg chaining support

Acked-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent ba2da2f8
...@@ -939,7 +939,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive) ...@@ -939,7 +939,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
/* group sequential buffers into one large buffer */ /* group sequential buffers into one large buffer */
addr = page_to_phys(sg->page) + sg->offset; addr = page_to_phys(sg->page) + sg->offset;
size = sg_dma_len(sg); size = sg_dma_len(sg);
while (sg++, --i) { while (--i) {
sg = sg_next(sg);
if ((addr + size) != page_to_phys(sg->page) + sg->offset) if ((addr + size) != page_to_phys(sg->page) + sg->offset)
break; break;
size += sg_dma_len(sg); size += sg_dma_len(sg);
......
...@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) ...@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
} }
} }
sg++; sg = sg_next(sg);
i--; i--;
} }
......
...@@ -846,7 +846,8 @@ void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq) ...@@ -846,7 +846,8 @@ void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
hwif->nsect = hwif->nleft = rq->nr_sectors; 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); EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
......
...@@ -1349,7 +1349,7 @@ static int hwif_init(ide_hwif_t *hwif) ...@@ -1349,7 +1349,7 @@ static int hwif_init(ide_hwif_t *hwif)
if (!hwif->sg_max_nents) if (!hwif->sg_max_nents)
hwif->sg_max_nents = PRD_ENTRIES; 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); GFP_KERNEL);
if (!hwif->sg_table) { if (!hwif->sg_table) {
printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/scatterlist.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) ...@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table; struct scatterlist *sg = hwif->sg_table;
struct scatterlist *cursg = hwif->cursg;
struct page *page; struct page *page;
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
unsigned long flags; unsigned long flags;
...@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) ...@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
unsigned int offset; unsigned int offset;
u8 *buf; u8 *buf;
page = sg[hwif->cursg].page; cursg = hwif->cursg;
offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE; if (!cursg) {
cursg = sg;
hwif->cursg = sg;
}
page = cursg->page;
offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
/* get the current page and offset */ /* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT)); page = nth_page(page, (offset >> PAGE_SHIFT));
...@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) ...@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
hwif->nleft--; hwif->nleft--;
hwif->cursg_ofs++; hwif->cursg_ofs++;
if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) { if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
hwif->cursg++; hwif->cursg = sg_next(hwif->cursg);
hwif->cursg_ofs = 0; hwif->cursg_ofs = 0;
} }
...@@ -367,6 +375,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, ...@@ -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) 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) { if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special; ide_task_t *task = rq->special;
......
...@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive) ...@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
cur_addr += tc; cur_addr += tc;
cur_len -= tc; cur_len -= tc;
} }
sg++; sg = sg_next(sg);
i--; i--;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/scatterlist.h>
#include <linux/ioc4.h> #include <linux/ioc4.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -537,7 +538,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) ...@@ -537,7 +538,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
} }
} }
sg++; sg = sg_next(sg);
i--; i--;
} }
......
...@@ -1539,7 +1539,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) ...@@ -1539,7 +1539,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
cur_len -= tc; cur_len -= tc;
++table; ++table;
} }
sg++; sg = sg_next(sg);
i--; i--;
} }
......
...@@ -772,7 +772,7 @@ typedef struct hwif_s { ...@@ -772,7 +772,7 @@ typedef struct hwif_s {
unsigned int nsect; unsigned int nsect;
unsigned int nleft; unsigned int nleft;
unsigned int cursg; struct scatterlist *cursg;
unsigned int cursg_ofs; unsigned int cursg_ofs;
int rqsize; /* max sectors per request */ int rqsize; /* max sectors per request */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment