diff options
-rw-r--r-- | drivers/ata/libata-core.c | 30 | ||||
-rw-r--r-- | include/linux/libata.h | 16 |
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 | */ |
1411 | unsigned ata_exec_internal_sg(struct ata_device *dev, | 1411 | unsigned 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, | |||
4825 | static void ata_pio_sector(struct ata_queued_cmd *qc) | 4828 | static 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 | ||
4961 | next_sg: | 4963 | next_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) | |||
1051 | static inline struct scatterlist * | 1052 | static inline struct scatterlist * |
1052 | ata_qc_first_sg(struct ata_queued_cmd *qc) | 1053 | ata_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; |