Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / drivers / ata / libata-sff.c
index 06daaa3..10ee22a 100644 (file)
 
 #include "libata.h"
 
+/**
+ *     ata_irq_on - Enable interrupts on a port.
+ *     @ap: Port on which interrupts are enabled.
+ *
+ *     Enable interrupts on a legacy IDE device using MMIO or PIO,
+ *     wait for idle, clear any pending interrupts.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+u8 ata_irq_on(struct ata_port *ap)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       u8 tmp;
+
+       ap->ctl &= ~ATA_NIEN;
+       ap->last_ctl = ap->ctl;
+
+       if (ap->flags & ATA_FLAG_MMIO)
+               writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
+       else
+               outb(ap->ctl, ioaddr->ctl_addr);
+       tmp = ata_wait_idle(ap);
+
+       ap->ops->irq_clear(ap);
+
+       return tmp;
+}
+
 /**
  *     ata_tf_load_pio - send taskfile registers to host controller
  *     @ap: Port to which output is sent
@@ -671,6 +700,14 @@ void ata_bmdma_freeze(struct ata_port *ap)
                writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
        else
                outb(ap->ctl, ioaddr->ctl_addr);
+
+       /* Under certain circumstances, some controllers raise IRQ on
+        * ATA_NIEN manipulation.  Also, many controllers fail to mask
+        * previously pending IRQ on ATA_NIEN assertion.  Clear it.
+        */
+       ata_chk_status(ap);
+
+       ap->ops->irq_clear(ap);
 }
 
 /**
@@ -714,7 +751,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
                        ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
                        ata_postreset_fn_t postreset)
 {
-       struct ata_eh_context *ehc = &ap->eh_context;
        struct ata_queued_cmd *qc;
        unsigned long flags;
        int thaw = 0;
@@ -732,9 +768,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
                   qc->tf.protocol == ATA_PROT_ATAPI_DMA)) {
                u8 host_stat;
 
-               host_stat = ata_bmdma_status(ap);
-
-               ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat);
+               host_stat = ap->ops->bmdma_status(ap);
 
                /* BMDMA controllers indicate host bus error by
                 * setting DMA_ERR bit and timing out.  As it wasn't
@@ -877,6 +911,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
                return NULL;
 
        probe_ent->n_ports = 2;
+       probe_ent->irq_flags = IRQF_SHARED;
 
        if (port_mask & ATA_PORT_PRIMARY) {
                probe_ent->irq = ATA_PRIMARY_IRQ;
@@ -981,6 +1016,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                mask = (1 << 2) | (1 << 0);
                if ((tmp8 & mask) != mask)
                        legacy_mode = (1 << 3);
+#if defined(CONFIG_NO_ATA_LEGACY)
+               /* Some platforms with PCI limits cannot address compat
+                  port space. In that case we punt if their firmware has
+                  left a device in compatibility mode */
+               if (legacy_mode) {
+                       printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
+                       return -EOPNOTSUPP;
+               }
+#endif
        }
 
        rc = pci_request_regions(pdev, DRV_NAME);