forked from Minki/linux
IDE: sg chaining support
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
ba2da2f8d6
commit
55c16a7004
@ -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);
|
||||
|
@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
|
||||
}
|
||||
}
|
||||
|
||||
sg++;
|
||||
sg = sg_next(sg);
|
||||
i--;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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--;
|
||||
}
|
||||
|
||||
|
@ -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--;
|
||||
}
|
||||
|
||||
|
@ -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--;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user