aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-02-21 13:11:32 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-21 13:11:32 -0500
commit52aa536f5a78bbba9205d296f53d2f8a424a3b08 (patch)
tree29ccde2430d7dd34420761b7fde4a8c8976fe76c
parent5914811acf36c3ff091f860a6964808f668f27d0 (diff)
parent2e242fa994428bd1a40b6a7e97430413246d0a16 (diff)
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
-rw-r--r--drivers/scsi/libata-core.c15
-rw-r--r--drivers/scsi/sata_qstor.c2
-rw-r--r--include/linux/libata.h16
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;
2756skip_map:
2757 sg_dma_len(sg) = sg->length; 2759 sg_dma_len(sg) = sg->length;
2758 2760
2761skip_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
559static inline struct scatterlist * 559static inline struct scatterlist *
560ata_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
569static inline struct scatterlist *
560ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) 570ata_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
572static inline unsigned int ata_tag_valid(unsigned int tag) 584static inline unsigned int ata_tag_valid(unsigned int tag)
573{ 585{