summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2007-08-18 18:27:36 +0900
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 11:21:01 +0200
commit0874ee76bcd06e2f53c32a56773ad82f5920f0f9 (patch)
treed38285f71ba3daaacf516b6dc3b98ccf2147d7e6 /drivers/ata
parentf1346372f9c73154727bf2cadb7f78126597efd2 (diff)
downloadlinux-0874ee76bcd06e2f53c32a56773ad82f5920f0f9.tar.gz
linux-0874ee76bcd06e2f53c32a56773ad82f5920f0f9.tar.bz2
linux-0874ee76bcd06e2f53c32a56773ad82f5920f0f9.zip
libata sg chaining support fix
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e52c33180e42..bbaa545ea999 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4952,16 +4952,18 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct scatterlist *sg = qc->__sg;
+ struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
struct ata_port *ap = qc->ap;
struct page *page;
unsigned char *buf;
unsigned int offset, count;
+ int no_more_sg = 0;
if (qc->curbytes + bytes >= qc->nbytes)
ap->hsm_task_state = HSM_ST_LAST;
next_sg:
- if (unlikely(qc->cursg == sg_last(qc->__sg, qc->n_elem))) {
+ if (unlikely(no_more_sg)) {
/*
* The end of qc->sg is reached and the device expects
* more data to transfer. In order not to overrun qc->sg
@@ -5023,6 +5025,9 @@ next_sg:
qc->cursg_ofs += count;
if (qc->cursg_ofs == sg->length) {
+ if (qc->cursg == lsg)
+ no_more_sg = 1;
+
qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0;
}