ahci: move ahci_sb600_softreset to libahci.c and rename it
authorYuan-Hsin Chen <yhchen@faraday-tech.com>
Tue, 21 Jun 2011 09:17:38 +0000 (17:17 +0800)
committerJeff Garzik <jgarzik@pobox.com>
Sat, 23 Jul 2011 21:57:36 +0000 (17:57 -0400)
ahci_sb600_softreset was in ahci.c. This function is used
to fix soft reset failure and renames as ahci_pmp_retry_softreset
in libahci.c.

Signed-off-by: Yuan-Hsin Chen <yhchen@faraday-tech.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/libahci.c

index 6ea99df87146ad250dffcb52b9c16997f61e7384..fd318ac364320bcc3110c8ba0d446decba19f0d7 100644 (file)
@@ -79,8 +79,6 @@ enum board_ids {
 };
 
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class,
-                         unsigned long deadline);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline);
 static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
@@ -104,12 +102,6 @@ static struct ata_port_operations ahci_p5wdh_ops = {
        .hardreset              = ahci_p5wdh_hardreset,
 };
 
-static struct ata_port_operations ahci_sb600_ops = {
-       .inherits               = &ahci_ops,
-       .softreset              = ahci_sb600_softreset,
-       .pmp_softreset          = ahci_sb600_softreset,
-};
-
 #define AHCI_HFLAGS(flags)     .private_data   = (void *)(flags)
 
 static const struct ata_port_info ahci_port_info[] = {
@@ -188,7 +180,7 @@ static const struct ata_port_info ahci_port_info[] = {
                .flags          = AHCI_FLAG_COMMON,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
-               .port_ops       = &ahci_sb600_ops,
+               .port_ops       = &ahci_pmp_retry_srst_ops,
        },
        [board_ahci_sb700] =    /* for SB700 and SB800 */
        {
@@ -196,7 +188,7 @@ static const struct ata_port_info ahci_port_info[] = {
                .flags          = AHCI_FLAG_COMMON,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
-               .port_ops       = &ahci_sb600_ops,
+               .port_ops       = &ahci_pmp_retry_srst_ops,
        },
        [board_ahci_vt8251] =
        {
@@ -502,54 +494,6 @@ static void ahci_pci_init_controller(struct ata_host *host)
        ahci_init_controller(host);
 }
 
-static int ahci_sb600_check_ready(struct ata_link *link)
-{
-       void __iomem *port_mmio = ahci_port_base(link->ap);
-       u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
-       u32 irq_status = readl(port_mmio + PORT_IRQ_STAT);
-
-       /*
-        * There is no need to check TFDATA if BAD PMP is found due to HW bug,
-        * which can save timeout delay.
-        */
-       if (irq_status & PORT_IRQ_BAD_PMP)
-               return -EIO;
-
-       return ata_check_ready(status);
-}
-
-static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class,
-                               unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       void __iomem *port_mmio = ahci_port_base(ap);
-       int pmp = sata_srst_pmp(link);
-       int rc;
-       u32 irq_sts;
-
-       DPRINTK("ENTER\n");
-
-       rc = ahci_do_softreset(link, class, pmp, deadline,
-                              ahci_sb600_check_ready);
-
-       /*
-        * Soft reset fails on some ATI chips with IPMS set when PMP
-        * is enabled but SATA HDD/ODD is connected to SATA port,
-        * do soft reset again to port 0.
-        */
-       if (rc == -EIO) {
-               irq_sts = readl(port_mmio + PORT_IRQ_STAT);
-               if (irq_sts & PORT_IRQ_BAD_PMP) {
-                       ata_link_warn(link,
-                                     "applying SB600 PMP SRST workaround and retrying\n");
-                       rc = ahci_do_softreset(link, class, 0, deadline,
-                                              ahci_check_ready);
-               }
-       }
-
-       return rc;
-}
-
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline)
 {
index 12c5282e7fca9c6effe1c42a2a7dae0a78395b2e..b1750007c8dc5603b23259c12d0b1b5639d07d48 100644 (file)
@@ -312,6 +312,7 @@ extern struct device_attribute *ahci_sdev_attrs[];
        .sdev_attrs             = ahci_sdev_attrs
 
 extern struct ata_port_operations ahci_ops;
+extern struct ata_port_operations ahci_pmp_retry_srst_ops;
 
 void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
                        u32 opts);
index c102d7d6428206795aeebe33a02980b089069cc7..3c92dbd751e0d287e2c124aa28e828ef46ad1858 100644 (file)
@@ -82,6 +82,8 @@ static void ahci_pmp_attach(struct ata_port *ap);
 static void ahci_pmp_detach(struct ata_port *ap);
 static int ahci_softreset(struct ata_link *link, unsigned int *class,
                          unsigned long deadline);
+static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
+                         unsigned long deadline);
 static int ahci_hardreset(struct ata_link *link, unsigned int *class,
                          unsigned long deadline);
 static void ahci_postreset(struct ata_link *link, unsigned int *class);
@@ -178,6 +180,12 @@ struct ata_port_operations ahci_ops = {
 };
 EXPORT_SYMBOL_GPL(ahci_ops);
 
+struct ata_port_operations ahci_pmp_retry_srst_ops = {
+       .inherits               = &ahci_ops,
+       .softreset              = ahci_pmp_retry_softreset,
+};
+EXPORT_SYMBOL_GPL(ahci_pmp_retry_srst_ops);
+
 int ahci_em_messages = 1;
 EXPORT_SYMBOL_GPL(ahci_em_messages);
 module_param(ahci_em_messages, int, 0444);
@@ -1319,6 +1327,55 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class,
 }
 EXPORT_SYMBOL_GPL(ahci_do_softreset);
 
+static int ahci_bad_pmp_check_ready(struct ata_link *link)
+{
+       void __iomem *port_mmio = ahci_port_base(link->ap);
+       u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
+       u32 irq_status = readl(port_mmio + PORT_IRQ_STAT);
+
+       /*
+        * There is no need to check TFDATA if BAD PMP is found due to HW bug,
+        * which can save timeout delay.
+        */
+       if (irq_status & PORT_IRQ_BAD_PMP)
+               return -EIO;
+
+       return ata_check_ready(status);
+}
+
+int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
+                               unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       void __iomem *port_mmio = ahci_port_base(ap);
+       int pmp = sata_srst_pmp(link);
+       int rc;
+       u32 irq_sts;
+
+       DPRINTK("ENTER\n");
+
+       rc = ahci_do_softreset(link, class, pmp, deadline,
+                              ahci_bad_pmp_check_ready);
+
+       /*
+        * Soft reset fails with IPMS set when PMP is enabled but
+        * SATA HDD/ODD is connected to SATA port, do soft reset
+        * again to port 0.
+        */
+       if (rc == -EIO) {
+               irq_sts = readl(port_mmio + PORT_IRQ_STAT);
+               if (irq_sts & PORT_IRQ_BAD_PMP) {
+                       ata_link_printk(link, KERN_WARNING,
+                                       "applying PMP SRST workaround "
+                                       "and retrying\n");
+                       rc = ahci_do_softreset(link, class, 0, deadline,
+                                              ahci_check_ready);
+               }
+       }
+
+       return rc;
+}
+
 static int ahci_hardreset(struct ata_link *link, unsigned int *class,
                          unsigned long deadline)
 {