Commit e1499647 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Alex Williamson

driver core: Better distinguish probe errors in really_probe

really_probe tries to special case errors from ->probe, but due to all
other initialization added to the function over time now a lot of
internal errors hit that code path as well.  Untangle that by adding
a new probe_err local variable and apply the special casing only to
that.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarKirti Wankhede <kwankhede@nvidia.com>
Link: https://lore.kernel.org/r/20210617142218.1877096-3-hch@lst.deSigned-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 204db60c
...@@ -513,12 +513,44 @@ static ssize_t state_synced_show(struct device *dev, ...@@ -513,12 +513,44 @@ static ssize_t state_synced_show(struct device *dev,
} }
static DEVICE_ATTR_RO(state_synced); static DEVICE_ATTR_RO(state_synced);
static int call_driver_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
if (dev->bus->probe)
ret = dev->bus->probe(dev);
else if (drv->probe)
ret = drv->probe(dev);
switch (ret) {
case 0:
break;
case -EPROBE_DEFER:
/* Driver requested deferred probing */
dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name);
break;
case -ENODEV:
case -ENXIO:
pr_debug("%s: probe of %s rejects match %d\n",
drv->name, dev_name(dev), ret);
break;
default:
/* driver matched but the probe failed */
pr_warn("%s: probe of %s failed with error %d\n",
drv->name, dev_name(dev), ret);
break;
}
return ret;
}
static int really_probe(struct device *dev, struct device_driver *drv) static int really_probe(struct device *dev, struct device_driver *drv)
{ {
int ret = -EPROBE_DEFER;
int local_trigger_count = atomic_read(&deferred_trigger_count); int local_trigger_count = atomic_read(&deferred_trigger_count);
bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) && bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) &&
!drv->suppress_bind_attrs; !drv->suppress_bind_attrs;
int ret = -EPROBE_DEFER, probe_ret = 0;
if (defer_all_probes) { if (defer_all_probes) {
/* /*
...@@ -572,14 +604,14 @@ static int really_probe(struct device *dev, struct device_driver *drv) ...@@ -572,14 +604,14 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto probe_failed; goto probe_failed;
} }
if (dev->bus->probe) { probe_ret = call_driver_probe(dev, drv);
ret = dev->bus->probe(dev); if (probe_ret) {
if (ret) /*
goto probe_failed; * Ignore errors returned by ->probe so that the next driver can
} else if (drv->probe) { * try its luck.
ret = drv->probe(dev); */
if (ret) ret = 0;
goto probe_failed; goto probe_failed;
} }
if (device_add_groups(dev, drv->dev_groups)) { if (device_add_groups(dev, drv->dev_groups)) {
...@@ -650,28 +682,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) ...@@ -650,28 +682,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
dev->pm_domain->dismiss(dev); dev->pm_domain->dismiss(dev);
pm_runtime_reinit(dev); pm_runtime_reinit(dev);
dev_pm_set_driver_flags(dev, 0); dev_pm_set_driver_flags(dev, 0);
if (probe_ret == -EPROBE_DEFER)
switch (ret) {
case -EPROBE_DEFER:
/* Driver requested deferred probing */
dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name);
driver_deferred_probe_add_trigger(dev, local_trigger_count); driver_deferred_probe_add_trigger(dev, local_trigger_count);
break;
case -ENODEV:
case -ENXIO:
pr_debug("%s: probe of %s rejects match %d\n",
drv->name, dev_name(dev), ret);
break;
default:
/* driver matched but the probe failed */
pr_warn("%s: probe of %s failed with error %d\n",
drv->name, dev_name(dev), ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret = 0;
done: done:
atomic_dec(&probe_count); atomic_dec(&probe_count);
wake_up_all(&probe_waitqueue); wake_up_all(&probe_waitqueue);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment