aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c30
-rw-r--r--include/linux/libata.h16
2 files changed, 26 insertions, 20 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 68699b3e7998..e52c33180e42 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
1410 */ 1410 */
1411unsigned ata_exec_internal_sg(struct ata_device *dev, 1411unsigned ata_exec_internal_sg(struct ata_device *dev,
1412 struct ata_taskfile *tf, const u8 *cdb, 1412 struct ata_taskfile *tf, const u8 *cdb,
1413 int dma_dir, struct scatterlist *sg, 1413 int dma_dir, struct scatterlist *sgl,
1414 unsigned int n_elem, unsigned long timeout) 1414 unsigned int n_elem, unsigned long timeout)
1415{ 1415{
1416 struct ata_link *link = dev->link; 1416 struct ata_link *link = dev->link;
@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
1472 qc->dma_dir = dma_dir; 1472 qc->dma_dir = dma_dir;
1473 if (dma_dir != DMA_NONE) { 1473 if (dma_dir != DMA_NONE) {
1474 unsigned int i, buflen = 0; 1474 unsigned int i, buflen = 0;
1475 struct scatterlist *sg;
1475 1476
1476 for (i = 0; i < n_elem; i++) 1477 for_each_sg(sgl, sg, n_elem, i)
1477 buflen += sg[i].length; 1478 buflen += sg->length;
1478 1479
1479 ata_sg_init(qc, sg, n_elem); 1480 ata_sg_init(qc, sgl, n_elem);
1480 qc->nbytes = buflen; 1481 qc->nbytes = buflen;
1481 } 1482 }
1482 1483
@@ -4292,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
4292 if (qc->n_elem) 4293 if (qc->n_elem)
4293 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); 4294 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
4294 /* restore last sg */ 4295 /* restore last sg */
4295 sg[qc->orig_n_elem - 1].length += qc->pad_len; 4296 sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
4296 if (pad_buf) { 4297 if (pad_buf) {
4297 struct scatterlist *psg = &qc->pad_sgent; 4298 struct scatterlist *psg = &qc->pad_sgent;
4298 void *addr = kmap_atomic(psg->page, KM_IRQ0); 4299 void *addr = kmap_atomic(psg->page, KM_IRQ0);
@@ -4547,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
4547 qc->orig_n_elem = 1; 4548 qc->orig_n_elem = 1;
4548 qc->buf_virt = buf; 4549 qc->buf_virt = buf;
4549 qc->nbytes = buflen; 4550 qc->nbytes = buflen;
4551 qc->cursg = qc->__sg;
4550 4552
4551 sg_init_one(&qc->sgent, buf, buflen); 4553 sg_init_one(&qc->sgent, buf, buflen);
4552} 4554}
@@ -4572,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4572 qc->__sg = sg; 4574 qc->__sg = sg;
4573 qc->n_elem = n_elem; 4575 qc->n_elem = n_elem;
4574 qc->orig_n_elem = n_elem; 4576 qc->orig_n_elem = n_elem;
4577 qc->cursg = qc->__sg;
4575} 4578}
4576 4579
4577/** 4580/**
@@ -4661,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
4661{ 4664{
4662 struct ata_port *ap = qc->ap; 4665 struct ata_port *ap = qc->ap;
4663 struct scatterlist *sg = qc->__sg; 4666 struct scatterlist *sg = qc->__sg;
4664 struct scatterlist *lsg = &sg[qc->n_elem - 1]; 4667 struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
4665 int n_elem, pre_n_elem, dir, trim_sg = 0; 4668 int n_elem, pre_n_elem, dir, trim_sg = 0;
4666 4669
4667 VPRINTK("ENTER, ata%u\n", ap->print_id); 4670 VPRINTK("ENTER, ata%u\n", ap->print_id);
@@ -4825,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
4825static void ata_pio_sector(struct ata_queued_cmd *qc) 4828static void ata_pio_sector(struct ata_queued_cmd *qc)
4826{ 4829{
4827 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 4830 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
4828 struct scatterlist *sg = qc->__sg;
4829 struct ata_port *ap = qc->ap; 4831 struct ata_port *ap = qc->ap;
4830 struct page *page; 4832 struct page *page;
4831 unsigned int offset; 4833 unsigned int offset;
@@ -4834,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
4834 if (qc->curbytes == qc->nbytes - qc->sect_size) 4836 if (qc->curbytes == qc->nbytes - qc->sect_size)
4835 ap->hsm_task_state = HSM_ST_LAST; 4837 ap->hsm_task_state = HSM_ST_LAST;
4836 4838
4837 page = sg[qc->cursg].page; 4839 page = qc->cursg->page;
4838 offset = sg[qc->cursg].offset + qc->cursg_ofs; 4840 offset = qc->cursg->offset + qc->cursg_ofs;
4839 4841
4840 /* get the current page and offset */ 4842 /* get the current page and offset */
4841 page = nth_page(page, (offset >> PAGE_SHIFT)); 4843 page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4863,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
4863 qc->curbytes += qc->sect_size; 4865 qc->curbytes += qc->sect_size;
4864 qc->cursg_ofs += qc->sect_size; 4866 qc->cursg_ofs += qc->sect_size;
4865 4867
4866 if (qc->cursg_ofs == (&sg[qc->cursg])->length) { 4868 if (qc->cursg_ofs == qc->cursg->length) {
4867 qc->cursg++; 4869 qc->cursg = sg_next(qc->cursg);
4868 qc->cursg_ofs = 0; 4870 qc->cursg_ofs = 0;
4869 } 4871 }
4870} 4872}
@@ -4959,7 +4961,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
4959 ap->hsm_task_state = HSM_ST_LAST; 4961 ap->hsm_task_state = HSM_ST_LAST;
4960 4962
4961next_sg: 4963next_sg:
4962 if (unlikely(qc->cursg >= qc->n_elem)) { 4964 if (unlikely(qc->cursg == sg_last(qc->__sg, qc->n_elem))) {
4963 /* 4965 /*
4964 * The end of qc->sg is reached and the device expects 4966 * The end of qc->sg is reached and the device expects
4965 * more data to transfer. In order not to overrun qc->sg 4967 * more data to transfer. In order not to overrun qc->sg
@@ -4982,7 +4984,7 @@ next_sg:
4982 return; 4984 return;
4983 } 4985 }
4984 4986
4985 sg = &qc->__sg[qc->cursg]; 4987 sg = qc->cursg;
4986 4988
4987 page = sg->page; 4989 page = sg->page;
4988 offset = sg->offset + qc->cursg_ofs; 4990 offset = sg->offset + qc->cursg_ofs;
@@ -5021,7 +5023,7 @@ next_sg:
5021 qc->cursg_ofs += count; 5023 qc->cursg_ofs += count;
5022 5024
5023 if (qc->cursg_ofs == sg->length) { 5025 if (qc->cursg_ofs == sg->length) {
5024 qc->cursg++; 5026 qc->cursg = sg_next(qc->cursg);
5025 qc->cursg_ofs = 0; 5027 qc->cursg_ofs = 0;
5026 } 5028 }
5027 5029
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 229a9ff9f924..377e6d4d9be3 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -29,7 +29,7 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <asm/scatterlist.h> 32#include <linux/scatterlist.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/ata.h> 34#include <linux/ata.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
@@ -416,6 +416,7 @@ struct ata_queued_cmd {
416 unsigned long flags; /* ATA_QCFLAG_xxx */ 416 unsigned long flags; /* ATA_QCFLAG_xxx */
417 unsigned int tag; 417 unsigned int tag;
418 unsigned int n_elem; 418 unsigned int n_elem;
419 unsigned int n_iter;
419 unsigned int orig_n_elem; 420 unsigned int orig_n_elem;
420 421
421 int dma_dir; 422 int dma_dir;
@@ -426,7 +427,7 @@ struct ata_queued_cmd {
426 unsigned int nbytes; 427 unsigned int nbytes;
427 unsigned int curbytes; 428 unsigned int curbytes;
428 429
429 unsigned int cursg; 430 struct scatterlist *cursg;
430 unsigned int cursg_ofs; 431 unsigned int cursg_ofs;
431 432
432 struct scatterlist sgent; 433 struct scatterlist sgent;
@@ -1043,7 +1044,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
1043 return 1; 1044 return 1;
1044 if (qc->pad_len) 1045 if (qc->pad_len)
1045 return 0; 1046 return 0;
1046 if (((sg - qc->__sg) + 1) == qc->n_elem) 1047 if (qc->n_iter == qc->n_elem)
1047 return 1; 1048 return 1;
1048 return 0; 1049 return 0;
1049} 1050}
@@ -1051,6 +1052,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
1051static inline struct scatterlist * 1052static inline struct scatterlist *
1052ata_qc_first_sg(struct ata_queued_cmd *qc) 1053ata_qc_first_sg(struct ata_queued_cmd *qc)
1053{ 1054{
1055 qc->n_iter = 0;
1054 if (qc->n_elem) 1056 if (qc->n_elem)
1055 return qc->__sg; 1057 return qc->__sg;
1056 if (qc->pad_len) 1058 if (qc->pad_len)
@@ -1063,8 +1065,8 @@ ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
1063{ 1065{
1064 if (sg == &qc->pad_sgent) 1066 if (sg == &qc->pad_sgent)
1065 return NULL; 1067 return NULL;
1066 if (++sg - qc->__sg < qc->n_elem) 1068 if (++qc->n_iter < qc->n_elem)
1067 return sg; 1069 return sg_next(sg);
1068 if (qc->pad_len) 1070 if (qc->pad_len)
1069 return &qc->pad_sgent; 1071 return &qc->pad_sgent;
1070 return NULL; 1072 return NULL;
@@ -1309,9 +1311,11 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
1309 qc->dma_dir = DMA_NONE; 1311 qc->dma_dir = DMA_NONE;
1310 qc->__sg = NULL; 1312 qc->__sg = NULL;
1311 qc->flags = 0; 1313 qc->flags = 0;
1312 qc->cursg = qc->cursg_ofs = 0; 1314 qc->cursg = NULL;
1315 qc->cursg_ofs = 0;
1313 qc->nbytes = qc->curbytes = 0; 1316 qc->nbytes = qc->curbytes = 0;
1314 qc->n_elem = 0; 1317 qc->n_elem = 0;
1318 qc->n_iter = 0;
1315 qc->err_mask = 0; 1319 qc->err_mask = 0;
1316 qc->pad_len = 0; 1320 qc->pad_len = 0;
1317 qc->sect_size = ATA_SECT_SIZE; 1321 qc->sect_size = ATA_SECT_SIZE;