]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/ahci.c
[SCSI] refactor sdev/starget/shost busy checking
[linux-2.6-omap-h63xx.git] / drivers / ata / ahci.c
index c729e6988bbb17db928de1cd903682cfc3dc2802..aeadd00411a187dc164eaa4abe4c3a447af8af59 100644 (file)
@@ -267,8 +267,8 @@ struct ahci_port_priv {
                                                 * per PM slot */
 };
 
-static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
 static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
@@ -316,6 +316,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
 
 static struct device_attribute *ahci_sdev_attrs[] = {
        &dev_attr_sw_activity,
+       &dev_attr_unload_heads,
        NULL
 };
 
@@ -420,7 +421,7 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci_mv */
        {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
-                                AHCI_HFLAG_MV_PATA),
+                                AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -487,7 +488,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
        { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
        { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+       { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
        { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+       { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -610,6 +613,15 @@ module_param(ahci_em_messages, int, 0444);
 MODULE_PARM_DESC(ahci_em_messages,
        "Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED");
 
+#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE)
+static int marvell_enable;
+#else
+static int marvell_enable = 1;
+#endif
+module_param(marvell_enable, int, 0644);
+MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
+
+
 static inline int ahci_nr_ports(u32 cap)
 {
        return (cap & 0x1f) + 1;
@@ -732,6 +744,8 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                           "MV_AHCI HACK: port_map %x -> %x\n",
                           port_map,
                           port_map & mv);
+               dev_printk(KERN_ERR, &pdev->dev,
+                         "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
 
                port_map &= mv;
        }
@@ -807,10 +821,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
        return 0;
 }
 
-static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
-       void __iomem *port_mmio = ahci_port_base(ap);
-       int offset = ahci_scr_offset(ap, sc_reg);
+       void __iomem *port_mmio = ahci_port_base(link->ap);
+       int offset = ahci_scr_offset(link->ap, sc_reg);
 
        if (offset) {
                *val = readl(port_mmio + offset);
@@ -819,10 +833,10 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return -EINVAL;
 }
 
-static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
-       void __iomem *port_mmio = ahci_port_base(ap);
-       int offset = ahci_scr_offset(ap, sc_reg);
+       void __iomem *port_mmio = ahci_port_base(link->ap);
+       int offset = ahci_scr_offset(link->ap, sc_reg);
 
        if (offset) {
                writel(val, port_mmio + offset);
@@ -960,7 +974,7 @@ static void ahci_disable_alpm(struct ata_port *ap)
        writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
 
        /* go ahead and clean out PhyRdy Change from Serror too */
-       ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+       ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
 
        /*
         * Clear flag to indicate that we should ignore all PhyRdy
@@ -1924,8 +1938,8 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
        ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);
 
        /* AHCI needs SError cleared; otherwise, it might lock up */
-       ahci_scr_read(ap, SCR_ERROR, &serror);
-       ahci_scr_write(ap, SCR_ERROR, serror);
+       ahci_scr_read(&ap->link, SCR_ERROR, &serror);
+       ahci_scr_write(&ap->link, SCR_ERROR, serror);
        host_ehi->serror |= serror;
 
        /* some controllers set IRQ_IF_ERR on device errors, ignore it */
@@ -2014,7 +2028,7 @@ static void ahci_port_intr(struct ata_port *ap)
        if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
                (status & PORT_IRQ_PHYRDY)) {
                status &= ~PORT_IRQ_PHYRDY;
-               ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+               ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
        }
 
        if (unlikely(status & PORT_IRQ_ERROR)) {
@@ -2533,6 +2547,12 @@ 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");
 
+       /* The AHCI driver can only drive the SATA ports, the PATA driver
+          can drive them all so if both drivers are selected make sure
+          AHCI stays out of the way */
+       if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
+               return -ENODEV;
+
        /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)