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 | { |
