ata: sata_sil: Continue probing other sata port when failed current port.
authorPeng Ma <peng.ma@nxp.com>
Wed, 4 Dec 2019 10:36:42 +0000 (10:36 +0000)
committerTom Rini <trini@konsulko.com>
Wed, 8 Jan 2020 14:27:44 +0000 (09:27 -0500)
In the initialization of sata driver, we want to initialize all port
 probes, Therefore, any detection failure between of them should continue
 initialization by skipping the current port instead of exit.

Signed-off-by: Peng Ma <peng.ma@nxp.com>
drivers/ata/sata_sil.c

index 4a50460..71ee0c0 100644 (file)
@@ -20,6 +20,7 @@
 #if CONFIG_IS_ENABLED(BLK)
 #include <dm.h>
 #include <blk.h>
+#include <dm/device-internal.h>
 #endif
 
 #include "sata_sil.h"
@@ -763,15 +764,33 @@ U_BOOT_DRIVER(sata_sil_driver) = {
        .platdata_auto_alloc_size = sizeof(struct sil_sata_priv),
 };
 
+static int sil_unbind_device(struct udevice *dev)
+{
+       int ret;
+
+       ret = device_remove(dev, DM_REMOVE_NORMAL);
+       if (ret)
+               return ret;
+
+       ret = device_unbind(dev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int sil_pci_probe(struct udevice *dev)
 {
        struct udevice *blk;
+       int failed_number;
        char sata_name[10];
        pci_dev_t devno;
        u16 word;
        int ret;
        int i;
 
+       failed_number = 0;
+
        /* Get PCI device number */
        devno = dm_pci_get_bdf(dev);
        if (devno == -1)
@@ -824,12 +843,44 @@ static int sil_pci_probe(struct udevice *dev)
                }
 
                ret = sil_init_sata(blk, i);
-               if (ret)
-                       return -ENODEV;
+               if (ret) {
+                       ret = sil_unbind_device(blk);
+                       if (ret)
+                               return ret;
+
+                       failed_number++;
+                       continue;
+               }
 
                ret = scan_sata(blk, i);
-               if (ret)
-                       return -ENODEV;
+               if (ret) {
+                       ret = sil_unbind_device(blk);
+                       if (ret)
+                               return ret;
+
+                       failed_number++;
+                       continue;
+               }
+       }
+
+       if (failed_number == sata_info.maxport)
+               return -ENODEV;
+       else
+               return 0;
+}
+
+static int sil_pci_remove(struct udevice *dev)
+{
+       int i;
+       struct sil_sata *sata;
+       struct sil_sata_priv *priv;
+
+       priv = dev_get_priv(dev);
+
+       for (i = sata_info.portbase; i < sata_info.maxport; i++) {
+               sata = priv->sil_sata_desc[i];
+               if (sata)
+                       free(sata);
        }
 
        return 0;
@@ -857,6 +908,7 @@ U_BOOT_DRIVER(sil_ahci_pci) = {
        .of_match = sil_pci_ids,
        .ops = &sata_sil_ops,
        .probe = sil_pci_probe,
+       .remove = sil_pci_remove,
        .priv_auto_alloc_size = sizeof(struct sil_sata_priv),
 };