diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 15 | ||||
-rw-r--r-- | drivers/scsi/sata_qstor.c | 2 | ||||
-rw-r--r-- | include/linux/libata.h | 16 |
3 files changed, 24 insertions, 9 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 62340f4ef004..70efde99f652 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2590,7 +2590,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2590 | WARN_ON(sg == NULL); | 2590 | WARN_ON(sg == NULL); |
2591 | 2591 | ||
2592 | if (qc->flags & ATA_QCFLAG_SINGLE) | 2592 | if (qc->flags & ATA_QCFLAG_SINGLE) |
2593 | WARN_ON(qc->n_elem != 1); | 2593 | WARN_ON(qc->n_elem > 1); |
2594 | 2594 | ||
2595 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); | 2595 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); |
2596 | 2596 | ||
@@ -2613,7 +2613,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2613 | kunmap_atomic(addr, KM_IRQ0); | 2613 | kunmap_atomic(addr, KM_IRQ0); |
2614 | } | 2614 | } |
2615 | } else { | 2615 | } else { |
2616 | if (sg_dma_len(&sg[0]) > 0) | 2616 | if (qc->n_elem) |
2617 | dma_unmap_single(ap->host_set->dev, | 2617 | dma_unmap_single(ap->host_set->dev, |
2618 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), | 2618 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), |
2619 | dir); | 2619 | dir); |
@@ -2646,7 +2646,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) | |||
2646 | unsigned int idx; | 2646 | unsigned int idx; |
2647 | 2647 | ||
2648 | WARN_ON(qc->__sg == NULL); | 2648 | WARN_ON(qc->__sg == NULL); |
2649 | WARN_ON(qc->n_elem == 0); | 2649 | WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); |
2650 | 2650 | ||
2651 | idx = 0; | 2651 | idx = 0; |
2652 | ata_for_each_sg(sg, qc) { | 2652 | ata_for_each_sg(sg, qc) { |
@@ -2791,6 +2791,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2791 | int dir = qc->dma_dir; | 2791 | int dir = qc->dma_dir; |
2792 | struct scatterlist *sg = qc->__sg; | 2792 | struct scatterlist *sg = qc->__sg; |
2793 | dma_addr_t dma_address; | 2793 | dma_addr_t dma_address; |
2794 | int trim_sg = 0; | ||
2794 | 2795 | ||
2795 | /* we must lengthen transfers to end on a 32-bit boundary */ | 2796 | /* we must lengthen transfers to end on a 32-bit boundary */ |
2796 | qc->pad_len = sg->length & 3; | 2797 | qc->pad_len = sg->length & 3; |
@@ -2810,13 +2811,15 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2810 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; | 2811 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; |
2811 | /* trim sg */ | 2812 | /* trim sg */ |
2812 | sg->length -= qc->pad_len; | 2813 | sg->length -= qc->pad_len; |
2814 | if (sg->length == 0) | ||
2815 | trim_sg = 1; | ||
2813 | 2816 | ||
2814 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", | 2817 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", |
2815 | sg->length, qc->pad_len); | 2818 | sg->length, qc->pad_len); |
2816 | } | 2819 | } |
2817 | 2820 | ||
2818 | if (!sg->length) { | 2821 | if (trim_sg) { |
2819 | sg_dma_address(sg) = 0; | 2822 | qc->n_elem--; |
2820 | goto skip_map; | 2823 | goto skip_map; |
2821 | } | 2824 | } |
2822 | 2825 | ||
@@ -2829,9 +2832,9 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2829 | } | 2832 | } |
2830 | 2833 | ||
2831 | sg_dma_address(sg) = dma_address; | 2834 | sg_dma_address(sg) = dma_address; |
2832 | skip_map: | ||
2833 | sg_dma_len(sg) = sg->length; | 2835 | sg_dma_len(sg) = sg->length; |
2834 | 2836 | ||
2837 | skip_map: | ||
2835 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), | 2838 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), |
2836 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); | 2839 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); |
2837 | 2840 | ||
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 286482630be3..9602f43a298e 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -277,7 +277,7 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) | |||
277 | u8 *prd = pp->pkt + QS_CPB_BYTES; | 277 | u8 *prd = pp->pkt + QS_CPB_BYTES; |
278 | 278 | ||
279 | WARN_ON(qc->__sg == NULL); | 279 | WARN_ON(qc->__sg == NULL); |
280 | WARN_ON(qc->n_elem == 0); | 280 | WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); |
281 | 281 | ||
282 | nelem = 0; | 282 | nelem = 0; |
283 | ata_for_each_sg(sg, qc) { | 283 | ata_for_each_sg(sg, qc) { |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 0d6bf50ad029..66b6847225df 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -616,17 +616,29 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) | |||
616 | } | 616 | } |
617 | 617 | ||
618 | static inline struct scatterlist * | 618 | static inline struct scatterlist * |
619 | ata_qc_first_sg(struct ata_queued_cmd *qc) | ||
620 | { | ||
621 | if (qc->n_elem) | ||
622 | return qc->__sg; | ||
623 | if (qc->pad_len) | ||
624 | return &qc->pad_sgent; | ||
625 | return NULL; | ||
626 | } | ||
627 | |||
628 | static inline struct scatterlist * | ||
619 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) | 629 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) |
620 | { | 630 | { |
621 | if (sg == &qc->pad_sgent) | 631 | if (sg == &qc->pad_sgent) |
622 | return NULL; | 632 | return NULL; |
623 | if (++sg - qc->__sg < qc->n_elem) | 633 | if (++sg - qc->__sg < qc->n_elem) |
624 | return sg; | 634 | return sg; |
625 | return qc->pad_len ? &qc->pad_sgent : NULL; | 635 | if (qc->pad_len) |
636 | return &qc->pad_sgent; | ||
637 | return NULL; | ||
626 | } | 638 | } |
627 | 639 | ||
628 | #define ata_for_each_sg(sg, qc) \ | 640 | #define ata_for_each_sg(sg, qc) \ |
629 | for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) | 641 | for (sg = ata_qc_first_sg(qc); sg; sg = ata_qc_next_sg(sg, qc)) |
630 | 642 | ||
631 | static inline unsigned int ata_tag_valid(unsigned int tag) | 643 | static inline unsigned int ata_tag_valid(unsigned int tag) |
632 | { | 644 | { |