diff options
Diffstat (limited to 'drivers/base/dd.c')
| -rw-r--r-- | drivers/base/dd.c | 29 | 
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index fd83817240e6..25341f52198c 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -607,10 +607,10 @@ re_probe:  	probe_ret = call_driver_probe(dev, drv);  	if (probe_ret) {  		/* -		 * Ignore errors returned by ->probe so that the next driver can -		 * try its luck. +		 * Return probe errors as positive values so that the callers +		 * can distinguish them from other errors.  		 */ -		ret = 0; +		ret = -probe_ret;  		goto probe_failed;  	} @@ -653,7 +653,6 @@ re_probe:  		dev->pm_domain->sync(dev);  	driver_bound(dev); -	ret = 1;  	pr_debug("bus: '%s': %s: bound device %s to driver %s\n",  		 drv->bus->name, __func__, dev_name(dev), drv->name);  	goto done; @@ -746,8 +745,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);   * @dev: device to try to bind to the driver   *   * This function returns -ENODEV if the device is not registered, -EBUSY if it - * already has a driver, and 1 if the device is bound successfully and 0 - * otherwise. + * already has a driver, 0 if the device is bound successfully and a positive + * (inverted) error code for failures from the ->probe method.   *   * This function must be called with @dev lock held.  When called for a   * USB interface, @dev->parent lock must be held as well. @@ -882,7 +881,14 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)  	if (data->check_async && async_allowed != data->want_async)  		return 0; -	return driver_probe_device(drv, dev); +	/* +	 * Ignore errors returned by ->probe so that the next driver can try +	 * its luck. +	 */ +	ret = driver_probe_device(drv, dev); +	if (ret < 0) +		return ret; +	return ret == 0;  }  static void __device_attach_async_helper(void *_dev, async_cookie_t cookie) @@ -1038,7 +1044,7 @@ static void __device_driver_unlock(struct device *dev, struct device *parent)   * @dev: Device to attach it to   *   * Manually attach driver to a device. Will acquire both @dev lock and - * @dev->parent lock if needed. + * @dev->parent lock if needed. Returns 0 on success, -ERR on failure.   */  int device_driver_attach(struct device_driver *drv, struct device *dev)  { @@ -1048,6 +1054,9 @@ int device_driver_attach(struct device_driver *drv, struct device *dev)  	ret = driver_probe_device(drv, dev);  	__device_driver_unlock(dev, dev->parent); +	/* also return probe errors as normal negative errnos */ +	if (ret > 0) +		ret = -ret;  	return ret;  } @@ -1114,7 +1123,9 @@ static int __driver_attach(struct device *dev, void *data)  		return 0;  	} -	device_driver_attach(drv, dev); +	__device_driver_lock(dev, dev->parent); +	driver_probe_device(drv, dev); +	__device_driver_unlock(dev, dev->parent);  	return 0;  }  | 
