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 */
|
/* 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sg++;
|
sg = sg_next(sg);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
cur_addr += tc;
|
cur_addr += tc;
|
||||||
cur_len -= tc;
|
cur_len -= tc;
|
||||||
}
|
}
|
||||||
sg++;
|
sg = sg_next(sg);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sg++;
|
sg = sg_next(sg);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in New Issue