aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2007-08-18 05:27:36 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 05:21:01 -0400
commit0874ee76bcd06e2f53c32a56773ad82f5920f0f9 (patch)
treed38285f71ba3daaacf516b6dc3b98ccf2147d7e6
parentf1346372f9c73154727bf2cadb7f78126597efd2 (diff)
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>
-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)
4952{ 4952{
4953 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 4953 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
4954 struct scatterlist *sg = qc->__sg; 4954 struct scatterlist *sg = qc->__sg;
4955 struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
4955 struct ata_port *ap = qc->ap; 4956 struct ata_port *ap = qc->ap;
4956 struct page *page; 4957 struct page *page;
4957 unsigned char *buf; 4958 unsigned char *buf;
4958 unsigned int offset, count; 4959 unsigned int offset, count;
4960 int no_more_sg = 0;
4959 4961
4960 if (qc->curbytes + bytes >= qc->nbytes) 4962 if (qc->curbytes + bytes >= qc->nbytes)
4961 ap->hsm_task_state = HSM_ST_LAST; 4963 ap->hsm_task_state = HSM_ST_LAST;
4962 4964
4963next_sg: 4965next_sg:
4964 if (unlikely(qc->cursg == sg_last(qc->__sg, qc->n_elem))) { 4966 if (unlikely(no_more_sg)) {
4965 /* 4967 /*
4966 * The end of qc->sg is reached and the device expects 4968 * The end of qc->sg is reached and the device expects
4967 * more data to transfer. In order not to overrun qc->sg 4969 * more data to transfer. In order not to overrun qc->sg
@@ -5023,6 +5025,9 @@ next_sg:
5023 qc->cursg_ofs += count; 5025 qc->cursg_ofs += count;
5024 5026
5025 if (qc->cursg_ofs == sg->length) { 5027 if (qc->cursg_ofs == sg->length) {
5028 if (qc->cursg == lsg)
5029 no_more_sg = 1;
5030
5026 qc->cursg = sg_next(qc->cursg); 5031 qc->cursg = sg_next(qc->cursg);
5027 qc->cursg_ofs = 0; 5032 qc->cursg_ofs = 0;
5028 } 5033 }