diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2012-01-24 13:34:24 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2012-01-24 19:00:34 -0500 |
commit | fde25a9b63b9a3dc91365c394a426ebe64cfc2da (patch) | |
tree | ecc24bd2702cb7cb32cd4d22729541d5c79cee39 /drivers/base/driver.c | |
parent | 2b31594a9523449b168946725689d039c80204de (diff) |
Driver core: driver_find() drops reference before returning
As part of the removal of get_driver()/put_driver(), this patch
(as1510) changes driver_find(); it now drops the reference it acquires
before returning. The patch also adjusts all the callers of
driver_find() to remove the now unnecessary calls to put_driver().
In addition, the patch adds a warning to driver_find(): Callers must
make sure the driver they are searching for does not get unloaded
while they are using it. This has always been the case; driver_find()
has never prevented a driver from being unregistered or unloaded.
Hence the patch will not introduce any new bugs. The existing callers
all seem to be okay in this respect, however I don't understand the
video drivers well enough to be certain about them.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Kyungmin Park <kyungmin.park@samsung.com>
CC: Andy Walls <awalls@md.metrocast.net>
CC: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/driver.c')
-rw-r--r-- | drivers/base/driver.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index b631f7c59453..e979cad75c6e 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -234,7 +234,6 @@ int driver_register(struct device_driver *drv) | |||
234 | 234 | ||
235 | other = driver_find(drv->name, drv->bus); | 235 | other = driver_find(drv->name, drv->bus); |
236 | if (other) { | 236 | if (other) { |
237 | put_driver(other); | ||
238 | printk(KERN_ERR "Error: Driver '%s' is already registered, " | 237 | printk(KERN_ERR "Error: Driver '%s' is already registered, " |
239 | "aborting...\n", drv->name); | 238 | "aborting...\n", drv->name); |
240 | return -EBUSY; | 239 | return -EBUSY; |
@@ -275,7 +274,9 @@ EXPORT_SYMBOL_GPL(driver_unregister); | |||
275 | * Call kset_find_obj() to iterate over list of drivers on | 274 | * Call kset_find_obj() to iterate over list of drivers on |
276 | * a bus to find driver by name. Return driver if found. | 275 | * a bus to find driver by name. Return driver if found. |
277 | * | 276 | * |
278 | * Note that kset_find_obj increments driver's reference count. | 277 | * This routine provides no locking to prevent the driver it returns |
278 | * from being unregistered or unloaded while the caller is using it. | ||
279 | * The caller is responsible for preventing this. | ||
279 | */ | 280 | */ |
280 | struct device_driver *driver_find(const char *name, struct bus_type *bus) | 281 | struct device_driver *driver_find(const char *name, struct bus_type *bus) |
281 | { | 282 | { |
@@ -283,6 +284,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus) | |||
283 | struct driver_private *priv; | 284 | struct driver_private *priv; |
284 | 285 | ||
285 | if (k) { | 286 | if (k) { |
287 | /* Drop reference added by kset_find_obj() */ | ||
288 | kobject_put(k); | ||
286 | priv = to_driver(k); | 289 | priv = to_driver(k); |
287 | return priv->driver; | 290 | return priv->driver; |
288 | } | 291 | } |