Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fde25a9b authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlan 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: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 2b31594a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -234,7 +234,6 @@ int driver_register(struct device_driver *drv)

	other = driver_find(drv->name, drv->bus);
	if (other) {
		put_driver(other);
		printk(KERN_ERR "Error: Driver '%s' is already registered, "
			"aborting...\n", drv->name);
		return -EBUSY;
@@ -275,7 +274,9 @@ EXPORT_SYMBOL_GPL(driver_unregister);
 * Call kset_find_obj() to iterate over list of drivers on
 * a bus to find driver by name. Return driver if found.
 *
 * Note that kset_find_obj increments driver's reference count.
 * This routine provides no locking to prevent the driver it returns
 * from being unregistered or unloaded while the caller is using it.
 * The caller is responsible for preventing this.
 */
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
@@ -283,6 +284,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus)
	struct driver_private *priv;

	if (k) {
		/* Drop reference added by kset_find_obj() */
		kobject_put(k);
		priv = to_driver(k);
		return priv->driver;
	}
+0 −1
Original line number Diff line number Diff line
@@ -449,7 +449,6 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut
	} else if ((drv = driver_find(buf, &gameport_bus)) != NULL) {
		gameport_disconnect_port(gameport);
		error = gameport_bind_driver(gameport, to_gameport_driver(drv));
		put_driver(drv);
	} else {
		error = -EINVAL;
	}
+0 −1
Original line number Diff line number Diff line
@@ -441,7 +441,6 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
		serio_disconnect_port(serio);
		error = serio_bind_driver(serio, to_serio_driver(drv));
		put_driver(drv);
		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
	} else {
		error = -EINVAL;
+0 −1
Original line number Diff line number Diff line
@@ -285,7 +285,6 @@ static void __exit cx18_alsa_exit(void)

	drv = driver_find("cx18", &pci_bus_type);
	ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
	put_driver(drv);

	cx18_ext_init = NULL;
	printk(KERN_INFO "cx18-alsa: module unload complete\n");
+0 −2
Original line number Diff line number Diff line
@@ -1293,7 +1293,6 @@ static int __init ivtvfb_init(void)

	drv = driver_find("ivtv", &pci_bus_type);
	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
	put_driver(drv);
	if (!registered) {
		printk(KERN_ERR "ivtvfb:  no cards found\n");
		return -ENODEV;
@@ -1310,7 +1309,6 @@ static void ivtvfb_cleanup(void)

	drv = driver_find("ivtv", &pci_bus_type);
	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
	put_driver(drv);
}

module_init(ivtvfb_init);
Loading