diff mbox

Failure with swiotlb

Message ID 20091230030200.GA2249@zhen-devel.sh.intel.com (mailing list archive)
State Rejected
Headers show

Commit Message

Zhenyu Wang Dec. 30, 2009, 3:02 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 30c36ac..0394449 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -16,9 +16,8 @@ 
  * on the Intel IOMMU support (CONFIG_DMAR).
  * Only newer chipsets need to bother with this, of course.
  */
-#ifdef CONFIG_DMAR
 #define USE_PCI_DMA_API 1
-#endif
+extern int iommu_detected;
 
 #define PCI_DEVICE_ID_INTEL_E7221_HB	0x2588
 #define PCI_DEVICE_ID_INTEL_E7221_IG	0x258a
@@ -191,17 +190,23 @@  static struct _intel_private {
 #ifdef USE_PCI_DMA_API
 static int intel_agp_map_page(struct page *page, dma_addr_t *ret)
 {
-	*ret = pci_map_page(intel_private.pcidev, page, 0,
-			    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-	if (pci_dma_mapping_error(intel_private.pcidev, *ret))
-		return -EINVAL;
+	if (iommu_detected) {
+		*ret = pci_map_page(intel_private.pcidev, page, 0,
+				    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(intel_private.pcidev, *ret))
+			return -EINVAL;
+	} else {
+		*ret = page_to_phys(page);
+	}
 	return 0;
 }
 
 static void intel_agp_unmap_page(struct page *page, dma_addr_t dma)
 {
-	pci_unmap_page(intel_private.pcidev, dma,
-		       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	if (iommu_detected) {
+		pci_unmap_page(intel_private.pcidev, dma,
+			       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	}
 }
 
 static void intel_agp_free_sglist(struct agp_memory *mem)
@@ -225,6 +230,9 @@  static int intel_agp_map_memory(struct agp_memory *mem)
 
 	DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
 
+	if (!iommu_detected)
+		return 0;
+
 	if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
 		return -ENOMEM;
 
@@ -246,17 +254,37 @@  static void intel_agp_unmap_memory(struct agp_memory *mem)
 {
 	DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count);
 
+	if (!iommu_detected)
+		return;
+
 	pci_unmap_sg(intel_private.pcidev, mem->sg_list,
 		     mem->page_count, PCI_DMA_BIDIRECTIONAL);
 	intel_agp_free_sglist(mem);
 }
 
+static void intel_agp_insert_memory(struct agp_memory *mem,
+					off_t pg_start, int mask_type)
+{
+	int i, j;
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		writel(agp_bridge->driver->mask_memory(agp_bridge,
+				page_to_phys(mem->pages[i]), mask_type),
+		       intel_private.gtt+j);
+	}
+
+	readl(intel_private.gtt+j-1);
+}
+
 static void intel_agp_insert_sg_entries(struct agp_memory *mem,
 					off_t pg_start, int mask_type)
 {
 	struct scatterlist *sg;
 	int i, j;
 
+	if (!iommu_detected)
+		return intel_agp_insert_memory(mem, pg_start, mask_type);
+
 	j = pg_start;
 
 	WARN_ON(!mem->num_sg);
@@ -287,22 +315,6 @@  static void intel_agp_insert_sg_entries(struct agp_memory *mem,
 	readl(intel_private.gtt+j-1);
 }
 
-#else
-
-static void intel_agp_insert_sg_entries(struct agp_memory *mem,
-					off_t pg_start, int mask_type)
-{
-	int i, j;
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		writel(agp_bridge->driver->mask_memory(agp_bridge,
-				page_to_phys(mem->pages[i]), mask_type),
-		       intel_private.gtt+j);
-	}
-
-	readl(intel_private.gtt+j-1);
-}
-
 #endif
 
 static int intel_i810_fetch_size(void)