]> git.hungrycats.org Git - linux/commitdiff
[libata ata_piix] Make sure annoying BIOSen don't disable our interrupts
authorJeff Garzik <jgarzik@redhat.com>
Mon, 8 Mar 2004 17:23:20 +0000 (12:23 -0500)
committerJeff Garzik <jgarzik@redhat.com>
Mon, 8 Mar 2004 17:23:20 +0000 (12:23 -0500)
drivers/scsi/ata_piix.c

index 4d3eee9720e3e1280ad1adc1814e05a176629a73..90001c648c56235adc5e92dc6edf262cafc4fde8 100644 (file)
 #include <linux/libata.h>
 
 #define DRV_NAME       "ata_piix"
-#define DRV_VERSION    "1.00"
+#define DRV_VERSION    "1.01"
 
 enum {
        PIIX_IOCFG              = 0x54, /* IDE I/O configuration register */
        ICH5_PCS                = 0x92, /* port control and status */
 
+       PIIX_FLAG_CHECKINTR     = (1 << 29), /* make sure PCI INTx enabled */
        PIIX_FLAG_COMBINED      = (1 << 30), /* combined mode possible */
 
        PIIX_COMB_PRI           = (1 << 0), /* combined mode, PATA primary */
@@ -163,7 +164,8 @@ static struct ata_port_info piix_port_info[] = {
        /* ich5_pata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .host_flags     = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+                                 PIIX_FLAG_CHECKINTR,
                .pio_mask       = 0x03, /* pio3-4 */
                .udma_mask      = ATA_UDMA_MASK_40C, /* FIXME: cbl det */
                .port_ops       = &piix_pata_ops,
@@ -172,8 +174,8 @@ static struct ata_port_info piix_port_info[] = {
        /* ich5_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
-                                 ATA_FLAG_SRST,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
+                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
                .pio_mask       = 0x03, /* pio3-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &piix_sata_ops,
@@ -518,6 +520,18 @@ static void piix_probe_combined (struct pci_dev *pdev, unsigned int *mask)
                *mask |= PIIX_COMB_PRI;
 }
 
+/* move to PCI layer, integrate w/ MSI stuff */
+static void pci_enable_intx(struct pci_dev *pdev)
+{
+       u16 pci_command;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+       if (pci_command & PCI_COMMAND_INTX_DISABLE) {
+               pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+       }
+}
+
 /**
  *     piix_init_one - Register PIIX ATA PCI device with kernel services
  *     @pdev: PCI device to register
@@ -552,6 +566,15 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (port_info[0]->host_flags & PIIX_FLAG_COMBINED)
                piix_probe_combined(pdev, &combined);
 
+       /* On ICH5, some BIOSen disable the interrupt using the
+        * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
+        * On ICH6, this bit has the same effect, but only when
+        * MSI is disabled (and it is disabled, as we don't use
+        * message-signalled interrupts currently).
+        */
+       if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
+               pci_enable_intx(pdev);
+
        if (combined & PIIX_COMB_PRI)
                sata_comb = 1;
        else if (combined & PIIX_COMB_SEC)