[2.5 PATCH] O2 coherency

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

 



Hi,

	This is a patch to ensure DMA coherency on the SGI O2, by adding
the appropriate cache flushes before and after DMA, and setting the
default page attribute to cacheable non-coherent.
It also fixes the flushed address for the ip27 (offset was missing).

Vivien.

================================================================================
diff -Naur linux/arch/mips64/sgi-ip27/ip27-pci-dma.c linux.patch/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- linux/arch/mips64/sgi-ip27/ip27-pci-dma.c	Thu Jan  3 21:24:54 2002
+++ linux.patch/arch/mips64/sgi-ip27/ip27-pci-dma.c	Sun Jul 14 22:29:34 2002
@@ -98,7 +98,8 @@
 
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nents; i++, sg++) {
-		sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
+		address = page_address(sg->page) + sg->offset;
+		sg->dvma_address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(address));
 	}
 
 	return nents;
diff -Naur linux/arch/mips64/sgi-ip32/ip32-pci-dma.c linux.patch/arch/mips64/sgi-ip32/ip32-pci-dma.c
--- linux/arch/mips64/sgi-ip32/ip32-pci-dma.c	Thu Jan  3 21:24:55 2002
+++ linux.patch/arch/mips64/sgi-ip32/ip32-pci-dma.c	Sun Jul 14 22:29:34 2002
@@ -44,7 +44,7 @@
 		dma_cache_wback_inv((unsigned long) ret, size);
 		*dma_handle = ( __pa (ret));
 		DPRINTK("pci_alloc_consistent: addr=%016lx; dma_handle=%08x\n",(u64)KSEG1ADDR(ret),*dma_handle);
-		return KSEG1ADDR(ret);
+		return((void *)KSEG1ADDR(ret));
 	}
 	DPRINTK("pci_alloc_consistent2: addr=%016lx; dma_handle=%08x\n",(u64)KSEG1ADDR(ret),*dma_handle);
 	return NULL;
@@ -85,7 +85,10 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	DPRINTK("pci_unmap_single\n");
-	/* Nothing to do */
+	if (direction != PCI_DMA_TODEVICE) {
+	        mips_wbflush();
+	        dma_cache_wback_inv((unsigned long)__va(dma_addr), size);
+	}
 }
 
 /*
@@ -108,6 +111,7 @@
 			     int nents, int direction)
 {
 	int i;
+	unsigned long address;
 
 	if (direction == PCI_DMA_NONE)
 		BUG();
@@ -117,9 +121,10 @@
 	DPRINTK("pci_map_sg\n");
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nents; i++, sg++) {
+		address = page_address(sg->page) + sg->offset;
 		mips_wbflush();
-		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
-		sg->address = (char *)(__pa(sg->address));
+		dma_cache_wback_inv(address, sg->length);
+		sg->dvma_address = __pa(address);
 	}
 
 	return nents;
@@ -133,10 +138,19 @@
 void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 				int nents, int direction)
 {
+	int i;
+	unsigned long address;
+
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	DPRINTK("pci_unmap_sg\n");
-	/* Nothing to do */
+	for (i = 0; i < nents; i++, sg++) {
+	  if (direction != PCI_DMA_TODEVICE) {
+		address = page_address(sg->page) + sg->offset;
+	        mips_wbflush();
+	        dma_cache_wback_inv(address, sg->length);
+	  }
+	}
 }
 
 /*
@@ -174,13 +188,16 @@
 				   int nelems, int direction)
 {
 	int i;
+	unsigned long address;
+
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	DPRINTK("pci_dma_sync_sg\n");
 	/*  Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++){
+		address = page_address(sg->page) + sg->offset;
 		mips_wbflush();
-		dma_cache_wback_inv((unsigned long)__va(sg->address), sg->length);
+		dma_cache_wback_inv(address, sg->length);
 	}
 /*	if(direction==PCI_DMA_TODEVICE)
 		mace_inv_read_buffers();*/
diff -Naur linux/include/asm-mips64/pci.h linux.patch/include/asm-mips64/pci.h
--- linux/include/asm-mips64/pci.h	Tue Jul  9 22:03:12 2002
+++ linux.patch/include/asm-mips64/pci.h	Sun Jul 14 22:29:34 2002
@@ -343,7 +343,7 @@
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_dma_address(sg)	((unsigned long)((sg)->address))
+#define sg_dma_address(sg)	((sg)->dvma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
 #endif /* __KERNEL__ */
diff -Naur linux/include/asm-mips64/pgtable.h linux.patch/include/asm-mips64/pgtable.h
--- linux/include/asm-mips64/pgtable.h	Mon Jul  8 22:28:12 2002
+++ linux.patch/include/asm-mips64/pgtable.h	Sun Jul 14 22:29:34 2002
@@ -188,11 +188,11 @@
 #ifdef CONFIG_MIPS_UNCACHED
 #define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED
 #else /* ! UNCACHED */
-#ifdef CONFIG_SGI_IP22
+#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP32)
 #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT
-#else /* ! IP22 */
+#else /* ! (IP22 || IP32)*/
 #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
-#endif /* IP22 */
+#endif /* (IP22 || IP32) */
 #endif /* UNCACHED */
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | PAGE_CACHABLE_DEFAULT)


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux