/** * bus_add_driver - Add a driver to the bus. * @drv: driver. * */ int bus_add_driver(struct device_driver * drv) { struct bus_type * bus = get_bus(drv->bus); int error = 0; if (bus) { pr_debug("bus %s: add driver %s\n", bus->name, drv->name); error = kobject_set_name(&drv->kobj, "%s", drv->name); if (error) { put_bus(bus); return error; } drv->kobj.kset = &bus->drivers; if ((error = kobject_register(&drv->kobj))) { put_bus(bus); return error; } driver_attach(drv); klist_add_tail(&drv->knode_bus, &bus->klist_drivers); module_add_driver(drv->owner, drv); driver_add_attrs(bus, drv); add_bind_files(drv); } return error; }
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) { if (get_bus(bus)) { sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } }
/* * Manually attach a device to a driver. * Note: the driver must want to bind to the device, * it is not possible to override the driver's id table. */ static ssize_t driver_bind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = get_bus(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); if (dev && dev->driver == NULL) { if (dev->parent) /* Needed for USB */ down(&dev->parent->sem); down(&dev->sem); err = driver_probe_device(drv, dev); up(&dev->sem); if (dev->parent) up(&dev->parent->sem); if (err > 0) /* success */ err = count; else if (err == 0) /* driver didn't accept device */ err = -ENODEV; } put_device(dev); put_bus(bus); return err; }
/** * bus_add_device - add device to bus * @dev: device being added * * - Add the device to its bus's list of devices. * - Create link to device's bus. */ int bus_add_device(struct device * dev) { struct bus_type * bus = get_bus(dev->bus); int error = 0; if (bus) { pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); if (error) goto out_put; error = sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); if (error) goto out_id; error = sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); if (error) goto out_subsys; error = make_deprecated_bus_links(dev); if (error) goto out_deprecated; } return 0; out_deprecated: sysfs_remove_link(&dev->kobj, "subsystem"); out_subsys: sysfs_remove_link(&bus->devices.kobj, dev->bus_id); out_id: device_remove_attrs(bus, dev); out_put: put_bus(dev->bus); return error; }
int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) { int error; if (get_bus(bus)) { error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } else error = -EINVAL; return error; }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove symlink from bus's directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device * dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); klist_remove(&dev->knode_bus); pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); } }
void bus_remove_driver(struct device_driver * drv) { if (drv->bus) { remove_bind_files(drv); driver_remove_attrs(drv->bus, drv); klist_remove(&drv->knode_bus); pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); driver_detach(drv); module_remove_driver(drv); kobject_unregister(&drv->kobj); put_bus(drv->bus); } }
static ssize_t driver_unbind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = get_bus(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); if (dev && dev->driver == drv) { device_release_driver(dev); err = count; } put_device(dev); put_bus(bus); return err; }
/** * bus_remove_device - remove device from bus * @dev: device to be removed * * - Remove symlink from bus's directory. * - Delete device from bus's list. * - Detach from its driver. * - Drop reference taken in bus_add_device(). */ void bus_remove_device(struct device * dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "subsystem"); remove_deprecated_bus_links(dev); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); if (dev->is_registered) { dev->is_registered = 0; klist_del(&dev->knode_bus); } pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); } }
/* * Manually attach a device to a driver. * Note: the driver must want to bind to the device, * it is not possible to override the driver's id table. */ static ssize_t driver_bind(struct device_driver *drv, const char *buf, size_t count) { struct bus_type *bus = get_bus(drv->bus); struct device *dev; int err = -ENODEV; dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); if (dev && dev->driver == NULL) { down(&dev->sem); err = driver_probe_device(drv, dev); up(&dev->sem); } put_device(dev); put_bus(bus); return err; }
/** * bus_add_driver - Add a driver to the bus. * @drv: driver. * */ int bus_add_driver(struct device_driver *drv) { struct bus_type * bus = get_bus(drv->bus); int error = 0; if (!bus) return 0; pr_debug("bus %s: add driver %s\n", bus->name, drv->name); error = kobject_set_name(&drv->kobj, "%s", drv->name); if (error) goto out_put_bus; drv->kobj.kset = &bus->drivers; if ((error = kobject_register(&drv->kobj))) goto out_put_bus; error = driver_attach(drv); if (error) goto out_unregister; klist_add_tail(&drv->knode_bus, &bus->klist_drivers); module_add_driver(drv->owner, drv); 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); } error = add_bind_files(drv); if (error) { /* Ditto */ printk(KERN_ERR "%s: add_bind_files(%s) failed\n", __FUNCTION__, drv->name); } return error; out_unregister: kobject_unregister(&drv->kobj); out_put_bus: put_bus(bus); return error; }