cciss: disable DMA refetch on Smart Array P600
authorMike Miller (OS Dev) <mikem@beardog.cca.cpqcorp.net>
Wed, 17 Oct 2007 08:10:04 +0000 (10:10 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 17 Oct 2007 08:10:04 +0000 (10:10 +0200)
This patch disables DMA refetch in the PCI bridge. We have disabled DMA
prefetch for quite some time. Testing with XEN revealed another ASIC bug. If
dom0 resides on a P600 the board can can an MCA bi accessing invalid memory
addresses. Apparently, we need to disable both prefetch and refetch.
My understanding is a refetch operation should not occur but it is a valid
thing to do if prefetched data is no longer available for whatever reason.
Please consider this patch for inclusion.

Signed-off-by: Mike Miller <mike.miller@hp.com>
Signed-off-by: Alex Chiang <achiang@hp.com>
--------------------------------------------------------------------------------
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
drivers/block/cciss.c

index 3fb7e8bc436d1b39eb579efc5ddc7b1222d69e4b..e330c26c5ad9c082b6f67c989cc44e36f1512167 100644 (file)
@@ -3035,15 +3035,20 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        }
 #endif
 
-       /* Disabling DMA prefetch for the P600
-        * An ASIC bug may result in a prefetch beyond
-        * physical memory.
+       /* Disabling DMA prefetch and refetch for the P600.
+        * An ASIC bug may result in accesses to invalid memory addresses.
+        * We've disabled prefetch for some time now. Testing with XEN
+        * kernels revealed a bug in the refetch if dom0 resides on a P600.
         */
        if(board_id == 0x3225103C) {
                __u32 dma_prefetch;
+               __u32 dma_refetch;
                dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG);
                dma_prefetch |= 0x8000;
                writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG);
+               pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch);
+               dma_refetch |= 0x1;
+               pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch);
        }
 
 #ifdef CCISS_DEBUG