{
struct driver_private *drv_priv = to_driver(kobj);
- pr_debug("driver: '%s': %s\n", kobject_name(kobj), __FUNCTION__);
+ pr_debug("driver: '%s': %s\n", kobject_name(kobj), __func__);
kfree(drv_priv);
}
#ifdef CONFIG_HOTPLUG
/* Manually detach a device from its associated driver. */
-static int driver_helper(struct device *dev, void *data)
-{
- const char *name = data;
-
- if (strcmp(name, dev->bus_id) == 0)
- return 1;
- return 0;
-}
-
static ssize_t driver_unbind(struct device_driver *drv,
const char *buf, size_t count)
{
struct device *dev;
int err = -ENODEV;
- dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+ dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == drv) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
struct device *dev;
int err = -ENODEV;
- dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+ dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == NULL) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
{
struct device *dev;
- dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+ dev = bus_find_device_by_name(bus, NULL, buf);
if (!dev)
return -ENODEV;
if (bus_rescan_devices_helper(dev, NULL) != 0)
}
EXPORT_SYMBOL_GPL(bus_find_device);
+static int match_name(struct device *dev, void *data)
+{
+ const char *name = data;
+
+ if (strcmp(name, dev->bus_id) == 0)
+ return 1;
+ return 0;
+}
+
+/**
+ * bus_find_device_by_name - device iterator for locating a particular device of a specific name
+ * @bus: bus type
+ * @start: Device to begin with
+ * @name: name of the device to match
+ *
+ * This is similar to the bus_find_device() function above, but it handles
+ * searching by a name automatically, no need to write another strcmp matching
+ * function.
+ */
+struct device *bus_find_device_by_name(struct bus_type *bus,
+ struct device *start, const char *name)
+{
+ return bus_find_device(bus, start, (void *)name, match_name);
+}
+EXPORT_SYMBOL_GPL(bus_find_device_by_name);
+
static struct device_driver *next_driver(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
int ret = 0;
if (bus) {
- dev->is_registered = 1;
if (bus->p->drivers_autoprobe)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
- else
- dev->is_registered = 0;
}
}
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev->bus_id);
device_remove_attrs(dev->bus, dev);
- if (dev->is_registered) {
- dev->is_registered = 0;
+ if (klist_node_attached(&dev->knode_bus))
klist_del(&dev->knode_bus);
- }
+
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev->bus_id);
device_release_driver(dev);
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
+ if (!priv) {
+ error = -ENOMEM;
+ goto out_put_bus;
+ }
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
if (error)
- goto out_put_bus;
+ goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
- __FUNCTION__, drv->name);
+ __func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
- __FUNCTION__, drv->name);
+ __func__, drv->name);
}
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
- __FUNCTION__, drv->name);
+ __func__, drv->name);
}
kobject_uevent(&priv->kobj, KOBJ_ADD);