[PATCH 5/8] block: convert libata to use blk_kmap helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Convert direct uses of kmap/unmap to blk_kmap/unmap in libata.  This
combined with the previous bio helper change fixes PIO cache coherency
bugs on architectures with aliased caches.

Signed-off-by: Tejun Heo <[email protected]>

---

 drivers/scsi/libata-core.c |   24 +++++++++++++++---------
 drivers/scsi/libata-scsi.c |    5 +++--
 2 files changed, 18 insertions(+), 11 deletions(-)

c1a1417612a1dc346baf783904d716c2e1d5f223
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f55b9b3..877a33c 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2491,9 +2491,10 @@ static void ata_sg_clean(struct ata_queu
 		sg[qc->orig_n_elem - 1].length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = blk_kmap_atomic(psg->page, KM_IRQ0,
+						     DMA_FROM_DEVICE);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
-			kunmap_atomic(addr, KM_IRQ0);
+			blk_kunmap_atomic(addr, KM_IRQ0, DMA_FROM_DEVICE);
 		}
 	} else {
 		if (sg_dma_len(&sg[0]) > 0)
@@ -2765,9 +2766,10 @@ static int ata_sg_setup(struct ata_queue
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = blk_kmap_atomic(psg->page, KM_IRQ0,
+						     DMA_TO_DEVICE);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
-			kunmap_atomic(addr, KM_IRQ0);
+			blk_kunmap_atomic(addr, KM_IRQ0, DMA_TO_DEVICE);
 		}
 
 		sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
@@ -3077,6 +3079,7 @@ static void ata_pio_sector(struct ata_qu
 	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 	struct scatterlist *sg = qc->__sg;
 	struct ata_port *ap = qc->ap;
+	enum dma_data_direction dir;
 	struct page *page;
 	unsigned int offset;
 	unsigned char *buf;
@@ -3084,6 +3087,7 @@ static void ata_pio_sector(struct ata_qu
 	if (qc->cursect == (qc->nsect - 1))
 		ap->hsm_task_state = HSM_ST_LAST;
 
+	dir = do_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
 	page = sg[qc->cursg].page;
 	offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
 
@@ -3091,7 +3095,7 @@ static void ata_pio_sector(struct ata_qu
 	page = nth_page(page, (offset >> PAGE_SHIFT));
 	offset %= PAGE_SIZE;
 
-	buf = kmap(page) + offset;
+	buf = blk_kmap(page, dir) + offset;
 
 	qc->cursect++;
 	qc->cursg_ofs++;
@@ -3104,10 +3108,9 @@ static void ata_pio_sector(struct ata_qu
 	DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 
 	/* do the actual data transfer */
-	do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 	ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);
 
-	kunmap(page);
+	blk_kunmap(page, dir);
 }
 
 /**
@@ -3127,6 +3130,7 @@ static void __atapi_pio_bytes(struct ata
 	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 	struct scatterlist *sg = qc->__sg;
 	struct ata_port *ap = qc->ap;
+	enum dma_data_direction dir;
 	struct page *page;
 	unsigned char *buf;
 	unsigned int offset, count;
@@ -3134,6 +3138,8 @@ static void __atapi_pio_bytes(struct ata
 	if (qc->curbytes + bytes >= qc->nbytes)
 		ap->hsm_task_state = HSM_ST_LAST;
 
+	dir = do_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
 next_sg:
 	if (unlikely(qc->cursg >= qc->n_elem)) {
 		/*
@@ -3173,7 +3179,7 @@ next_sg:
 	/* don't cross page boundaries */
 	count = min(count, (unsigned int)PAGE_SIZE - offset);
 
-	buf = kmap(page) + offset;
+	buf = blk_kmap(page, dir) + offset;
 
 	bytes -= count;
 	qc->curbytes += count;
@@ -3189,7 +3195,7 @@ next_sg:
 	/* do the actual data transfer */
 	ata_data_xfer(ap, buf, count, do_write);
 
-	kunmap(page);
+	blk_kunmap(page, dir);
 
 	if (bytes)
 		goto next_sg;
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index cfbceb5..8f8a19a 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1372,7 +1372,8 @@ static unsigned int ata_scsi_rbuf_get(st
 		struct scatterlist *sg;
 
 		sg = (struct scatterlist *) cmd->request_buffer;
-		buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+		buf = blk_kmap_atomic(sg->page, KM_USER0, DMA_FROM_DEVICE);
+		buf += sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = cmd->request_buffer;
@@ -1400,7 +1401,7 @@ static inline void ata_scsi_rbuf_put(str
 		struct scatterlist *sg;
 
 		sg = (struct scatterlist *) cmd->request_buffer;
-		kunmap_atomic(buf - sg->offset, KM_USER0);
+		blk_kunmap_atomic(buf - sg->offset, KM_USER0, DMA_FROM_DEVICE);
 	}
 }
 
-- 
1.0.6


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux