libata: update libata core layer to use devres
[powerpc.git] / drivers / ata / ahci.c
index f36da48..d725683 100644 (file)
@@ -75,6 +75,7 @@ enum {
        AHCI_CMD_CLR_BUSY       = (1 << 10),
 
        RX_FIS_D2H_REG          = 0x40, /* offset of D2H Register FIS data */
+       RX_FIS_SDB              = 0x58, /* offset of SDB FIS data */
        RX_FIS_UNK              = 0x60, /* offset of Unknown FIS data */
 
        board_ahci              = 0,
@@ -202,6 +203,10 @@ struct ahci_port_priv {
        dma_addr_t              cmd_tbl_dma;
        void                    *rx_fis;
        dma_addr_t              rx_fis_dma;
+       /* for NCQ spurious interrupt analysis */
+       int                     ncq_saw_spurious_sdb_cnt;
+       unsigned int            ncq_saw_d2h:1;
+       unsigned int            ncq_saw_dmas:1;
 };
 
 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
@@ -361,7 +366,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
        { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
        { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
-       { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */
+       { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */
        { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
        { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
        { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
@@ -402,6 +407,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci },            /* MCP65 */
        { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci },            /* MCP65 */
        { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci },            /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci },            /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci },            /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci },            /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci },            /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci },            /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci },            /* MCP67 */
@@ -418,7 +431,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 
        /* Generic, PCI class code for AHCI */
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-         0x010601, 0xffffff, board_ahci },
+         PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
 
        { }     /* terminate list */
 };
@@ -578,35 +591,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
 {
        u32 cmd, scontrol;
 
-       cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
-
-       if (cap & HOST_CAP_SSC) {
-               /* enable transitions to slumber mode */
-               scontrol = readl(port_mmio + PORT_SCR_CTL);
-               if ((scontrol & 0x0f00) > 0x100) {
-                       scontrol &= ~0xf00;
-                       writel(scontrol, port_mmio + PORT_SCR_CTL);
-               }
-
-               /* put device into slumber mode */
-               writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD);
-
-               /* wait for the transition to complete */
-               ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER,
-                                 PORT_CMD_ICC_SLUMBER, 1, 50);
-       }
+       if (!(cap & HOST_CAP_SSS))
+               return;
 
-       /* put device into listen mode */
-       if (cap & HOST_CAP_SSS) {
-               /* first set PxSCTL.DET to 0 */
-               scontrol = readl(port_mmio + PORT_SCR_CTL);
-               scontrol &= ~0xf;
-               writel(scontrol, port_mmio + PORT_SCR_CTL);
+       /* put device into listen mode, first set PxSCTL.DET to 0 */
+       scontrol = readl(port_mmio + PORT_SCR_CTL);
+       scontrol &= ~0xf;
+       writel(scontrol, port_mmio + PORT_SCR_CTL);
 
-               /* then set PxCMD.SUD to 0 */
-               cmd &= ~PORT_CMD_SPIN_UP;
-               writel(cmd, port_mmio + PORT_CMD);
-       }
+       /* then set PxCMD.SUD to 0 */
+       cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
+       cmd &= ~PORT_CMD_SPIN_UP;
+       writel(cmd, port_mmio + PORT_CMD);
 }
 
 static void ahci_init_port(void __iomem *port_mmio, u32 cap,
@@ -645,8 +641,6 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
        u32 cap_save, impl_save, tmp;
 
        cap_save = readl(mmio + HOST_CAP);
-       cap_save &= ( (1<<28) | (1<<17) );
-       cap_save |= (1 << 27);
        impl_save = readl(mmio + HOST_PORTS_IMPL);
 
        /* global controller reset */
@@ -909,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
 
        /* clear D2H reception area to properly wait for D2H FIS */
        ata_tf_init(ap->device, &tf);
-       tf.command = 0xff;
+       tf.command = 0x80;
        ata_tf_to_fis(&tf, d2h_fis, 0);
 
        rc = sata_std_hardreset(ap, class);
@@ -1120,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap)
        void __iomem *mmio = ap->host->mmio_base;
        void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        struct ata_eh_info *ehi = &ap->eh_info;
+       struct ahci_port_priv *pp = ap->private_data;
        u32 status, qc_active;
-       int rc;
+       int rc, known_irq = 0;
 
        status = readl(port_mmio + PORT_IRQ_STAT);
        writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1148,17 +1143,53 @@ static void ahci_host_intr(struct ata_port *ap)
 
        /* hmmm... a spurious interupt */
 
-       /* some devices send D2H reg with I bit set during NCQ command phase */
-       if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
+       /* if !NCQ, ignore.  No modern ATA device has broken HSM
+        * implementation for non-NCQ commands.
+        */
+       if (!ap->sactive)
                return;
 
-       /* ignore interim PIO setup fis interrupts */
-       if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
-               return;
+       if (status & PORT_IRQ_D2H_REG_FIS) {
+               if (!pp->ncq_saw_d2h)
+                       ata_port_printk(ap, KERN_INFO,
+                               "D2H reg with I during NCQ, "
+                               "this message won't be printed again\n");
+               pp->ncq_saw_d2h = 1;
+               known_irq = 1;
+       }
+
+       if (status & PORT_IRQ_DMAS_FIS) {
+               if (!pp->ncq_saw_dmas)
+                       ata_port_printk(ap, KERN_INFO,
+                               "DMAS FIS during NCQ, "
+                               "this message won't be printed again\n");
+               pp->ncq_saw_dmas = 1;
+               known_irq = 1;
+       }
+
+       if (status & PORT_IRQ_SDB_FIS &&
+                  pp->ncq_saw_spurious_sdb_cnt < 10) {
+               /* SDB FIS containing spurious completions might be
+                * dangerous, we need to know more about them.  Print
+                * more of it.
+                */
+               const __le32 *f = pp->rx_fis + RX_FIS_SDB;
+
+               ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ "
+                               "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n",
+                               readl(port_mmio + PORT_CMD_ISSUE),
+                               readl(port_mmio + PORT_SCR_ACT),
+                               le32_to_cpu(f[0]), le32_to_cpu(f[1]),
+                               pp->ncq_saw_spurious_sdb_cnt < 10 ?
+                               "" : ", shutting up");
+
+               pp->ncq_saw_spurious_sdb_cnt++;
+               known_irq = 1;
+       }
 
-       if (ata_ratelimit())
+       if (!known_irq)
                ata_port_printk(ap, KERN_INFO, "spurious interrupt "
-                               "(irq_stat 0x%x active_tag %d sactive 0x%x)\n",
+                               "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
                                status, ap->active_tag, ap->sactive);
 }
 
@@ -1251,7 +1282,7 @@ static void ahci_thaw(struct ata_port *ap)
        /* clear IRQ */
        tmp = readl(port_mmio + PORT_IRQ_STAT);
        writel(tmp, port_mmio + PORT_IRQ_STAT);
-       writel(1 << ap->id, mmio + HOST_IRQ_STAT);
+       writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
 
        /* turn IRQ back on */
        writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
@@ -1366,7 +1397,9 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
        void __iomem *mmio = host->mmio_base;
        int rc;
 
-       ata_pci_device_do_resume(pdev);
+       rc = ata_pci_device_do_resume(pdev);
+       if (rc)
+               return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
                rc = ahci_reset_controller(mmio, pdev);
@@ -1588,11 +1621,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
                speed_s = "?";
 
        pci_read_config_word(pdev, 0x0a, &cc);
-       if (cc == 0x0101)
+       if (cc == PCI_CLASS_STORAGE_IDE)
                scc_s = "IDE";
-       else if (cc == 0x0106)
+       else if (cc == PCI_CLASS_STORAGE_SATA)
                scc_s = "SATA";
-       else if (cc == 0x0104)
+       else if (cc == PCI_CLASS_STORAGE_RAID)
                scc_s = "RAID";
        else
                scc_s = "unknown";
@@ -1654,13 +1687,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-       /* JMicron-specific fixup: make sure we're in AHCI mode */
-       /* This is protected from races with ata_jmicron by the pci probe
-          locking */
        if (pdev->vendor == PCI_VENDOR_ID_JMICRON) {
-               /* AHCI enable, AHCI on function 0 */
-               pci_write_config_byte(pdev, 0x41, 0xa1);
-               /* Function 1 is the PATA controller */
+               /* Function 1 is the PATA controller except on the 368, where
+                  we are not AHCI anyway */
                if (PCI_FUNC(pdev->devfn))
                        return -ENODEV;
        }
@@ -1755,38 +1784,24 @@ err_out:
        return rc;
 }
 
-static void ahci_remove_one (struct pci_dev *pdev)
+static void ahci_remove_one(struct pci_dev *pdev)
 {
        struct device *dev = pci_dev_to_dev(pdev);
        struct ata_host *host = dev_get_drvdata(dev);
        struct ahci_host_priv *hpriv = host->private_data;
-       unsigned int i;
-       int have_msi;
 
-       for (i = 0; i < host->n_ports; i++)
-               ata_port_detach(host->ports[i]);
+       ata_host_remove(host);
 
-       have_msi = hpriv->flags & AHCI_FLAG_MSI;
-       free_irq(host->irq, host);
-
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               ata_scsi_release(ap->scsi_host);
-               scsi_host_put(ap->scsi_host);
-       }
-
-       kfree(hpriv);
        pci_iounmap(pdev, host->mmio_base);
-       kfree(host);
 
-       if (have_msi)
+       if (hpriv->flags & AHCI_FLAG_MSI)
                pci_disable_msi(pdev);
        else
                pci_intx(pdev, 0);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        dev_set_drvdata(dev, NULL);
+       kfree(hpriv);
 }
 
 static int __init ahci_init(void)