diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-21 13:11:32 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-21 13:11:32 -0500 |
| commit | 52aa536f5a78bbba9205d296f53d2f8a424a3b08 (patch) | |
| tree | 29ccde2430d7dd34420761b7fde4a8c8976fe76c | |
| parent | 5914811acf36c3ff091f860a6964808f668f27d0 (diff) | |
| parent | 2e242fa994428bd1a40b6a7e97430413246d0a16 (diff) | |
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
| -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 7ddd5a69352a..5f1d7580218d 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
| @@ -2514,7 +2514,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
| 2514 | assert(sg != NULL); | 2514 | assert(sg != NULL); |
| 2515 | 2515 | ||
| 2516 | if (qc->flags & ATA_QCFLAG_SINGLE) | 2516 | if (qc->flags & ATA_QCFLAG_SINGLE) |
| 2517 | assert(qc->n_elem == 1); | 2517 | assert(qc->n_elem <= 1); |
| 2518 | 2518 | ||
| 2519 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); | 2519 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); |
| 2520 | 2520 | ||
| @@ -2537,7 +2537,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
| 2537 | kunmap_atomic(addr, KM_IRQ0); | 2537 | kunmap_atomic(addr, KM_IRQ0); |
| 2538 | } | 2538 | } |
| 2539 | } else { | 2539 | } else { |
| 2540 | if (sg_dma_len(&sg[0]) > 0) | 2540 | if (qc->n_elem) |
| 2541 | dma_unmap_single(ap->host_set->dev, | 2541 | dma_unmap_single(ap->host_set->dev, |
| 2542 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), | 2542 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), |
| 2543 | dir); | 2543 | dir); |
| @@ -2570,7 +2570,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) | |||
| 2570 | unsigned int idx; | 2570 | unsigned int idx; |
| 2571 | 2571 | ||
| 2572 | assert(qc->__sg != NULL); | 2572 | assert(qc->__sg != NULL); |
| 2573 | assert(qc->n_elem > 0); | 2573 | assert(qc->n_elem > 0 || qc->pad_len > 0); |
| 2574 | 2574 | ||
| 2575 | idx = 0; | 2575 | idx = 0; |
| 2576 | ata_for_each_sg(sg, qc) { | 2576 | ata_for_each_sg(sg, qc) { |
| @@ -2715,6 +2715,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
| 2715 | int dir = qc->dma_dir; | 2715 | int dir = qc->dma_dir; |
| 2716 | struct scatterlist *sg = qc->__sg; | 2716 | struct scatterlist *sg = qc->__sg; |
| 2717 | dma_addr_t dma_address; | 2717 | dma_addr_t dma_address; |
| 2718 | int trim_sg = 0; | ||
| 2718 | 2719 | ||
| 2719 | /* we must lengthen transfers to end on a 32-bit boundary */ | 2720 | /* we must lengthen transfers to end on a 32-bit boundary */ |
| 2720 | qc->pad_len = sg->length & 3; | 2721 | qc->pad_len = sg->length & 3; |
| @@ -2734,13 +2735,15 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
| 2734 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; | 2735 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; |
| 2735 | /* trim sg */ | 2736 | /* trim sg */ |
| 2736 | sg->length -= qc->pad_len; | 2737 | sg->length -= qc->pad_len; |
| 2738 | if (sg->length == 0) | ||
| 2739 | trim_sg = 1; | ||
| 2737 | 2740 | ||
| 2738 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", | 2741 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", |
| 2739 | sg->length, qc->pad_len); | 2742 | sg->length, qc->pad_len); |
| 2740 | } | 2743 | } |
| 2741 | 2744 | ||
| 2742 | if (!sg->length) { | 2745 | if (trim_sg) { |
| 2743 | sg_dma_address(sg) = 0; | 2746 | qc->n_elem--; |
| 2744 | goto skip_map; | 2747 | goto skip_map; |
| 2745 | } | 2748 | } |
| 2746 | 2749 | ||
| @@ -2753,9 +2756,9 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
| 2753 | } | 2756 | } |
| 2754 | 2757 | ||
| 2755 | sg_dma_address(sg) = dma_address; | 2758 | sg_dma_address(sg) = dma_address; |
| 2756 | skip_map: | ||
| 2757 | sg_dma_len(sg) = sg->length; | 2759 | sg_dma_len(sg) = sg->length; |
| 2758 | 2760 | ||
| 2761 | skip_map: | ||
| 2759 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), | 2762 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), |
| 2760 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); | 2763 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); |
| 2761 | 2764 | ||
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index de05e2883f9c..80480f0fb2b8 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 | assert(qc->__sg != NULL); | 279 | assert(qc->__sg != NULL); |
| 280 | assert(qc->n_elem > 0); | 280 | assert(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 9e5db2949c58..c91be5e64ede 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -557,17 +557,29 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) | |||
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | static inline struct scatterlist * | 559 | static inline struct scatterlist * |
| 560 | ata_qc_first_sg(struct ata_queued_cmd *qc) | ||
| 561 | { | ||
| 562 | if (qc->n_elem) | ||
| 563 | return qc->__sg; | ||
| 564 | if (qc->pad_len) | ||
| 565 | return &qc->pad_sgent; | ||
| 566 | return NULL; | ||
| 567 | } | ||
| 568 | |||
| 569 | static inline struct scatterlist * | ||
| 560 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) | 570 | ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) |
| 561 | { | 571 | { |
| 562 | if (sg == &qc->pad_sgent) | 572 | if (sg == &qc->pad_sgent) |
| 563 | return NULL; | 573 | return NULL; |
| 564 | if (++sg - qc->__sg < qc->n_elem) | 574 | if (++sg - qc->__sg < qc->n_elem) |
| 565 | return sg; | 575 | return sg; |
| 566 | return qc->pad_len ? &qc->pad_sgent : NULL; | 576 | if (qc->pad_len) |
| 577 | return &qc->pad_sgent; | ||
| 578 | return NULL; | ||
| 567 | } | 579 | } |
| 568 | 580 | ||
| 569 | #define ata_for_each_sg(sg, qc) \ | 581 | #define ata_for_each_sg(sg, qc) \ |
| 570 | for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) | 582 | for (sg = ata_qc_first_sg(qc); sg; sg = ata_qc_next_sg(sg, qc)) |
| 571 | 583 | ||
| 572 | static inline unsigned int ata_tag_valid(unsigned int tag) | 584 | static inline unsigned int ata_tag_valid(unsigned int tag) |
| 573 | { | 585 | { |
