libata: implement spurious irq handling for SFF and apply it to piix
[safe/jmp/linux-2.6] / drivers / ata / ata_piix.c
index 3aadded..c338066 100644 (file)
@@ -173,6 +173,7 @@ static int piix_sidpr_scr_read(struct ata_link *link,
                               unsigned int reg, u32 *val);
 static int piix_sidpr_scr_write(struct ata_link *link,
                                unsigned int reg, u32 val);
+static bool piix_irq_check(struct ata_port *ap);
 #ifdef CONFIG_PM
 static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -291,6 +292,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (PCH) */
        { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (CPT) */
+       { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (CPT) */
+       { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (CPT) */
+       { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (CPT) */
+       { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
 };
 
@@ -309,8 +318,13 @@ static struct scsi_host_template piix_sht = {
        ATA_BMDMA_SHT(DRV_NAME),
 };
 
-static struct ata_port_operations piix_pata_ops = {
+static struct ata_port_operations piix_sata_ops = {
        .inherits               = &ata_bmdma32_port_ops,
+       .sff_irq_check          = piix_irq_check,
+};
+
+static struct ata_port_operations piix_pata_ops = {
+       .inherits               = &piix_sata_ops,
        .cable_detect           = ata_cable_40wire,
        .set_piomode            = piix_set_piomode,
        .set_dmamode            = piix_set_dmamode,
@@ -328,10 +342,6 @@ static struct ata_port_operations ich_pata_ops = {
        .set_dmamode            = ich_set_dmamode,
 };
 
-static struct ata_port_operations piix_sata_ops = {
-       .inherits               = &ata_bmdma_port_ops,
-};
-
 static struct ata_port_operations piix_sidpr_sata_ops = {
        .inherits               = &piix_sata_ops,
        .hardreset              = sata_std_hardreset,
@@ -869,10 +879,10 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
                                (timings[pio][1] << 8);
                }
 
-               if (ap->udma_mask) {
+               if (ap->udma_mask)
                        udma_enable &= ~(1 << devid);
-                       pci_write_config_word(dev, master_port, master_data);
-               }
+
+               pci_write_config_word(dev, master_port, master_data);
        }
        /* Don't scribble on 0x48 if the controller does not support UDMA */
        if (ap->udma_mask)
@@ -962,6 +972,14 @@ static int piix_sidpr_scr_write(struct ata_link *link,
        return 0;
 }
 
+static bool piix_irq_check(struct ata_port *ap)
+{
+       if (unlikely(!ap->ioaddr.bmdma_addr))
+               return false;
+
+       return ap->ops->bmdma_status(ap) & ATA_DMA_INTR;
+}
+
 #ifdef CONFIG_PM
 static int piix_broken_suspend(void)
 {