ata: sata_rescan must scan for block devices
A system may have multiple SATA controller. Removing the controller with the lowest sequence number before probing all SATA controllers makes no sense. In sata_rescan we remove all block devices which are children of SATA controllers. We also have to remove the bootdev devices as they will be created when scanning for block devices. After probing all SATA controllers we must scan for block devices otherwise we end up without any SATA block device. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Reviewed-by: Tony Dinh <mibodhi@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:

committed by
Tom Rini

parent
a60c20bda8
commit
101d9a6a53
@@ -9,9 +9,12 @@
|
|||||||
* Dave Liu <daveliu@freescale.com>
|
* Dave Liu <daveliu@freescale.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY UCLASS_AHCI
|
||||||
|
|
||||||
#include <ahci.h>
|
#include <ahci.h>
|
||||||
#include <blk.h>
|
#include <blk.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <log.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <sata.h>
|
#include <sata.h>
|
||||||
#include <dm/device-internal.h>
|
#include <dm/device-internal.h>
|
||||||
@@ -49,38 +52,39 @@ int sata_scan(struct udevice *dev)
|
|||||||
|
|
||||||
int sata_rescan(bool verbose)
|
int sata_rescan(bool verbose)
|
||||||
{
|
{
|
||||||
|
struct uclass *uc;
|
||||||
|
struct udevice *dev; /* SATA controller */
|
||||||
int ret;
|
int ret;
|
||||||
struct udevice *dev;
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("Removing devices on SATA bus...\n");
|
printf("scanning bus for devices...\n");
|
||||||
|
|
||||||
blk_unbind_all(UCLASS_AHCI);
|
ret = uclass_get(UCLASS_AHCI, &uc);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = uclass_find_first_device(UCLASS_AHCI, &dev);
|
/* Remove all children of SATA devices (blk and bootdev) */
|
||||||
if (ret || !dev) {
|
uclass_foreach_dev(dev, uc) {
|
||||||
printf("Cannot find SATA device (err=%d)\n", ret);
|
log_debug("unbind %s\n", dev->name);
|
||||||
return -ENOENT;
|
ret = device_chld_remove(dev, NULL, DM_REMOVE_NORMAL);
|
||||||
}
|
if (!ret)
|
||||||
|
ret = device_chld_unbind(dev, NULL);
|
||||||
ret = device_remove(dev, DM_REMOVE_NORMAL);
|
if (ret && verbose) {
|
||||||
if (ret) {
|
log_err("Unbinding from %s failed (%dE)\n",
|
||||||
printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name, ret);
|
dev->name, ret);
|
||||||
return -ENOSYS;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("Rescanning SATA bus for devices...\n");
|
printf("Rescanning SATA bus for devices...\n");
|
||||||
|
|
||||||
ret = uclass_probe_all(UCLASS_AHCI);
|
uclass_foreach_dev_probe(UCLASS_AHCI, dev) {
|
||||||
|
ret = sata_scan(dev);
|
||||||
if (ret == -ENODEV) {
|
if (ret && verbose)
|
||||||
if (verbose)
|
log_err("Scanning %s failed (%dE)\n", dev->name, ret);
|
||||||
printf("No SATA block device found\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
|
static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
|
||||||
|
Reference in New Issue
Block a user