[libata] ahci: Add SATA GEN3 related messages
[firefly-linux-kernel-4.4.55.git] / drivers / ata / libata-core.c
index fecca4223f8ee92adfe4e4824ef6114def00baa2..9ae583554c8b79791b42e544caf14648adbfddaf 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/workqueue.h>
 #include <linux/scatterlist.h>
 #include <linux/io.h>
+#include <linux/async.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -1006,6 +1007,7 @@ static const char *sata_spd_string(unsigned int spd)
        static const char * const spd_str[] = {
                "1.5 Gbps",
                "3.0 Gbps",
+               "6.0 Gbps",
        };
 
        if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
@@ -5909,6 +5911,54 @@ void ata_host_init(struct ata_host *host, struct device *dev,
        host->ops = ops;
 }
 
+
+static void async_port_probe(void *data, async_cookie_t cookie)
+{
+       int rc;
+       struct ata_port *ap = data;
+       /* probe */
+       if (ap->ops->error_handler) {
+               struct ata_eh_info *ehi = &ap->link.eh_info;
+               unsigned long flags;
+
+               ata_port_probe(ap);
+
+               /* kick EH for boot probing */
+               spin_lock_irqsave(ap->lock, flags);
+
+               ehi->probe_mask |= ATA_ALL_DEVICES;
+               ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
+               ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
+
+               ap->pflags &= ~ATA_PFLAG_INITIALIZING;
+               ap->pflags |= ATA_PFLAG_LOADING;
+               ata_port_schedule_eh(ap);
+
+               spin_unlock_irqrestore(ap->lock, flags);
+
+               /* wait for EH to finish */
+               ata_port_wait_eh(ap);
+       } else {
+               DPRINTK("ata%u: bus probe begin\n", ap->print_id);
+               rc = ata_bus_probe(ap);
+               DPRINTK("ata%u: bus probe end\n", ap->print_id);
+
+               if (rc) {
+                       /* FIXME: do something useful here?
+                        * Current libata behavior will
+                        * tear down everything when
+                        * the module is removed
+                        * or the h/w is unplugged.
+                        */
+               }
+       }
+
+       /* in order to keep device order, we need to synchronize at this point */
+       async_synchronize_cookie(cookie);
+
+       ata_scsi_scan_host(ap, 1);
+
+}
 /**
  *     ata_host_register - register initialized ATA host
  *     @host: ATA host to register
@@ -5988,52 +6038,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        DPRINTK("probe begin\n");
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
-
-               /* probe */
-               if (ap->ops->error_handler) {
-                       struct ata_eh_info *ehi = &ap->link.eh_info;
-                       unsigned long flags;
-
-                       ata_port_probe(ap);
-
-                       /* kick EH for boot probing */
-                       spin_lock_irqsave(ap->lock, flags);
-
-                       ehi->probe_mask |= ATA_ALL_DEVICES;
-                       ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
-                       ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
-                       ap->pflags &= ~ATA_PFLAG_INITIALIZING;
-                       ap->pflags |= ATA_PFLAG_LOADING;
-                       ata_port_schedule_eh(ap);
-
-                       spin_unlock_irqrestore(ap->lock, flags);
-
-                       /* wait for EH to finish */
-                       ata_port_wait_eh(ap);
-               } else {
-                       DPRINTK("ata%u: bus probe begin\n", ap->print_id);
-                       rc = ata_bus_probe(ap);
-                       DPRINTK("ata%u: bus probe end\n", ap->print_id);
-
-                       if (rc) {
-                               /* FIXME: do something useful here?
-                                * Current libata behavior will
-                                * tear down everything when
-                                * the module is removed
-                                * or the h/w is unplugged.
-                                */
-                       }
-               }
-       }
-
-       /* probes are done, now scan each port's disk(s) */
-       DPRINTK("host probe begin\n");
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               ata_scsi_scan_host(ap, 1);
+               async_schedule(async_port_probe, ap);
        }
+       DPRINTK("probe end\n");
 
        return 0;
 }