WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] linux: fix swiotlb sync functions to properly deal w

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] linux: fix swiotlb sync functions to properly deal with DMA_BIDIRECTIONAL
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Mon, 13 Sep 2010 14:58:27 +0100
Cc: dominic.curran@xxxxxxxxxx
Delivery-date: Mon, 13 Sep 2010 06:59:58 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
This change was left out from a merge somewhere between 2.6.12 and 2.6.16.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Cc: Dominic Curran <dominic.curran@xxxxxxxxxx>

--- a/lib/swiotlb-xen.c
+++ b/lib/swiotlb-xen.c
@@ -47,6 +47,14 @@ EXPORT_SYMBOL(swiotlb);
  */
 #define IO_TLB_SHIFT 11
 
+/*
+ * Enumeration for sync targets
+ */
+enum dma_sync_target {
+       SYNC_FOR_CPU = 0,
+       SYNC_FOR_DEVICE = 1,
+};
+
 int swiotlb_force;
 
 static char *iotlb_virt_start;
@@ -444,11 +452,26 @@ unmap_single(struct device *hwdev, char 
 }
 
 static void
-sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
+sync_single(struct device *hwdev, char *dma_addr, size_t size,
+           int dir, int target)
 {
        struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
-       BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
-       __sync_single(buffer, dma_addr, size, dir);
+       switch (target) {
+       case SYNC_FOR_CPU:
+               if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
+                       __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE);
+               else
+                       BUG_ON(dir != DMA_TO_DEVICE);
+               break;
+       case SYNC_FOR_DEVICE:
+               if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
+                       __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
+               else
+                       BUG_ON(dir != DMA_FROM_DEVICE);
+               break;
+       default:
+               BUG();
+       }
 }
 
 static void
@@ -543,22 +566,27 @@ swiotlb_unmap_single(struct device *hwde
  * address back to the card, you must first perform a
  * swiotlb_dma_sync_for_device, and then the device again owns the buffer
  */
+static inline void
+swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
+                   size_t size, int dir, int target)
+{
+       BUG_ON(dir == DMA_NONE);
+       if (in_swiotlb_aperture(dev_addr))
+               sync_single(hwdev, bus_to_virt(dev_addr), size, dir, target);
+}
+
 void
 swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
                            size_t size, int dir)
 {
-       BUG_ON(dir == DMA_NONE);
-       if (in_swiotlb_aperture(dev_addr))
-               sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
+       swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
 }
 
 void
 swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
                               size_t size, int dir)
 {
-       BUG_ON(dir == DMA_NONE);
-       if (in_swiotlb_aperture(dev_addr))
-               sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
+       swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
 }
 
 /*
@@ -642,9 +670,9 @@ swiotlb_unmap_sg(struct device *hwdev, s
  * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
  * and usage.
  */
-void
-swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
-                       int nelems, int dir)
+static inline void
+swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
+               int nelems, int dir, int target)
 {
        int i;
 
@@ -652,24 +680,22 @@ swiotlb_sync_sg_for_cpu(struct device *h
 
        for (i = 0; i < nelems; i++, sg++)
                if (in_swiotlb_aperture(sg->dma_address))
-                       sync_single(hwdev,
-                                   (void *)bus_to_virt(sg->dma_address),
-                                   sg->dma_length, dir);
+                       sync_single(hwdev, bus_to_virt(sg->dma_address),
+                                   sg->dma_length, dir, target);
+}
+
+void
+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
+                       int nelems, int dir)
+{
+       swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
 }
 
 void
 swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
                           int nelems, int dir)
 {
-       int i;
-
-       BUG_ON(dir == DMA_NONE);
-
-       for (i = 0; i < nelems; i++, sg++)
-               if (in_swiotlb_aperture(sg->dma_address))
-                       sync_single(hwdev,
-                                   (void *)bus_to_virt(sg->dma_address),
-                                   sg->dma_length, dir);
+       swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
 }
 
 #ifdef CONFIG_HIGHMEM



Attachment: xen-swiotlb-sync-bidirectional.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] linux: fix swiotlb sync functions to properly deal with DMA_BIDIRECTIONAL, Jan Beulich <=