]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
atl1: disable broken 64-bit DMA
authorLuca Tettamanti <kronos.it@gmail.com>
Sat, 24 Nov 2007 19:15:18 +0000 (13:15 -0600)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 14 Dec 2007 18:31:54 +0000 (10:31 -0800)
atl1: disable broken 64-bit DMA

[ Upstream commit: 5f08e46b621a769e52a9545a23ab1d5fb2aec1d4 ]

The L1 network chip can DMA to 64-bit addresses, but multiple descriptor
rings share a single register for the high 32 bits of their address, so
only a single, aligned, 4 GB physical address range can be used at a time.
As a result, we need to confine the driver to a 32-bit DMA mask, otherwise
we see occasional data corruption errors in systems containing 4 or more
gigabytes of RAM.

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/atl1/atl1_main.c

index 6862c11ff86408972ca124ab6813ee52fe497c0b..1b7a5a894ab80fc47208b636c44a551983bf5879 100644 (file)
@@ -2097,21 +2097,26 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
        struct net_device *netdev;
        struct atl1_adapter *adapter;
        static int cards_found = 0;
-       bool pci_using_64 = true;
        int err;
 
        err = pci_enable_device(pdev);
        if (err)
                return err;
 
-       err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+       /*
+        * The atl1 chip can DMA to 64-bit addresses, but it uses a single
+        * shared register for the high 32 bits, so only a single, aligned,
+        * 4 GB physical address range can be used at a time.
+        *
+        * Supporting 64-bit DMA on this hardware is more trouble than it's
+        * worth.  It is far easier to limit to 32-bit DMA than update
+        * various kernel subsystems to support the mechanics required by a
+        * fixed-high-32-bit system.
+        */
+       err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (err) {
-               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-               if (err) {
-                       dev_err(&pdev->dev, "no usable DMA configuration\n");
-                       goto err_dma;
-               }
-               pci_using_64 = false;
+               dev_err(&pdev->dev, "no usable DMA configuration\n");
+               goto err_dma;
        }
        /* Mark all PCI regions associated with PCI device
         * pdev as being reserved by owner atl1_driver_name
@@ -2176,7 +2181,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 
        netdev->ethtool_ops = &atl1_ethtool_ops;
        adapter->bd_number = cards_found;
-       adapter->pci_using_64 = pci_using_64;
 
        /* setup the private structure */
        err = atl1_sw_init(adapter);
@@ -2193,9 +2197,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
         */
        /* netdev->features |= NETIF_F_TSO; */
 
-       if (pci_using_64)
-               netdev->features |= NETIF_F_HIGHDMA;
-
        netdev->features |= NETIF_F_LLTX;
 
        /*