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 /drivers/ide/ide-taskfile.c | |
parent | ba2da2f8d61a9d2e24754c6311a4ab6a5e70060a (diff) |
IDE: sg chaining support
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 18 |
1 files changed, 14 insertions, 4 deletions
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 | ||