[PATCH] libata: ata_piix 450NX errata
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Thu, 8 Dec 2005 19:22:28 +0000 (19:22 +0000)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 13 Dec 2005 04:23:03 +0000 (23:23 -0500)
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
drivers/scsi/ata_piix.c

index 908ff1f9671a1bd82c02daf26a1ba7ba6032fc89..0ea27873b9fffaa054ec6b535d60a8afe8a59337 100644 (file)
@@ -619,6 +619,40 @@ static int piix_disable_ahci(struct pci_dev *pdev)
        return rc;
 }
 
+/**
+ *     piix_check_450nx_errata -       Check for problem 450NX setup
+ *     
+ *     Check for the present of 450NX errata #19 and errata #25. If
+ *     they are found return an error code so we can turn off DMA
+ */
+
+static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
+{
+       struct pci_dev *pdev = NULL;
+       u16 cfg;
+       u8 rev;
+       int no_piix_dma = 0;
+       
+       while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
+       {
+               /* Look for 450NX PXB. Check for problem configurations
+                  A PCI quirk checks bit 6 already */
+               pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+               pci_read_config_word(pdev, 0x41, &cfg);
+               /* Only on the original revision: IDE DMA can hang */
+               if(rev == 0x00)
+                       no_piix_dma = 1;
+               /* On all revisions below 5 PXB bus lock must be disabled for IDE */
+               else if(cfg & (1<<14) && rev < 5)
+                       no_piix_dma = 2;
+       }
+       if(no_piix_dma)
+               dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n");
+       if(no_piix_dma == 2)
+               dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n");
+       return no_piix_dma;
+}              
+
 /**
  *     piix_init_one - Register PIIX ATA PCI device with kernel services
  *     @pdev: PCI device to register
@@ -693,7 +727,15 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                           "combined mode detected (p=%u, s=%u)\n",
                           pata_chan, sata_chan);
        }
-
+       if (piix_check_450nx_errata(pdev)) {
+               /* This writes into the master table but it does not
+                  really matter for this errata as we will apply it to
+                  all the PIIX devices on the board */
+               port_info[0]->mwdma_mask = 0;
+               port_info[0]->udma_mask = 0;
+               port_info[1]->mwdma_mask = 0;
+               port_info[1]->udma_mask = 0;
+       }
        return ata_pci_init_one(pdev, port_info, 2);
 }