linux-mips
[Top] [All Lists]

[2.5 PATCH] O2 coherency

To: Ralf Baechle <ralf@oss.sgi.com>
Subject: [2.5 PATCH] O2 coherency
From: Vivien Chappelier <vivien.chappelier@enst-bretagne.fr>
Date: Sun, 14 Jul 2002 22:49:39 +0200 (CEST)
Cc: linux-mips@oss.sgi.com
Sender: owner-linux-mips@oss.sgi.com
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)


<Prev in Thread] Current Thread [Next in Thread>
  • [2.5 PATCH] O2 coherency, Vivien Chappelier <=