11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * bus.c - bus driver management 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 2002-3 Patrick Mochel 51da177e4SLinus Torvalds * Copyright (c) 2002-3 Open Source Development Labs 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * This file is released under the GPLv2 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/config.h> 121da177e4SLinus Torvalds #include <linux/device.h> 131da177e4SLinus Torvalds #include <linux/module.h> 141da177e4SLinus Torvalds #include <linux/errno.h> 151da177e4SLinus Torvalds #include <linux/init.h> 161da177e4SLinus Torvalds #include <linux/string.h> 171da177e4SLinus Torvalds #include "base.h" 181da177e4SLinus Torvalds #include "power/power.h" 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds #define to_dev(node) container_of(node, struct device, bus_list) 211da177e4SLinus Torvalds #define to_drv(node) container_of(node, struct device_driver, kobj.entry) 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) 241da177e4SLinus Torvalds #define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj) 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* 271da177e4SLinus Torvalds * sysfs bindings for drivers 281da177e4SLinus Torvalds */ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) 311da177e4SLinus Torvalds #define to_driver(obj) container_of(obj, struct device_driver, kobj) 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds static ssize_t 351da177e4SLinus Torvalds drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 361da177e4SLinus Torvalds { 371da177e4SLinus Torvalds struct driver_attribute * drv_attr = to_drv_attr(attr); 381da177e4SLinus Torvalds struct device_driver * drv = to_driver(kobj); 39*4a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds if (drv_attr->show) 421da177e4SLinus Torvalds ret = drv_attr->show(drv, buf); 431da177e4SLinus Torvalds return ret; 441da177e4SLinus Torvalds } 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds static ssize_t 471da177e4SLinus Torvalds drv_attr_store(struct kobject * kobj, struct attribute * attr, 481da177e4SLinus Torvalds const char * buf, size_t count) 491da177e4SLinus Torvalds { 501da177e4SLinus Torvalds struct driver_attribute * drv_attr = to_drv_attr(attr); 511da177e4SLinus Torvalds struct device_driver * drv = to_driver(kobj); 52*4a0c20bfSDmitry Torokhov ssize_t ret = -EIO; 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds if (drv_attr->store) 551da177e4SLinus Torvalds ret = drv_attr->store(drv, buf, count); 561da177e4SLinus Torvalds return ret; 571da177e4SLinus Torvalds } 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds static struct sysfs_ops driver_sysfs_ops = { 601da177e4SLinus Torvalds .show = drv_attr_show, 611da177e4SLinus Torvalds .store = drv_attr_store, 621da177e4SLinus Torvalds }; 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds static void driver_release(struct kobject * kobj) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds struct device_driver * drv = to_driver(kobj); 681da177e4SLinus Torvalds complete(&drv->unloaded); 691da177e4SLinus Torvalds } 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds static struct kobj_type ktype_driver = { 721da177e4SLinus Torvalds .sysfs_ops = &driver_sysfs_ops, 731da177e4SLinus Torvalds .release = driver_release, 741da177e4SLinus Torvalds }; 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds /* 781da177e4SLinus Torvalds * sysfs bindings for buses 791da177e4SLinus Torvalds */ 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds static ssize_t 831da177e4SLinus Torvalds bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 841da177e4SLinus Torvalds { 851da177e4SLinus Torvalds struct bus_attribute * bus_attr = to_bus_attr(attr); 861da177e4SLinus Torvalds struct bus_type * bus = to_bus(kobj); 871da177e4SLinus Torvalds ssize_t ret = 0; 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds if (bus_attr->show) 901da177e4SLinus Torvalds ret = bus_attr->show(bus, buf); 911da177e4SLinus Torvalds return ret; 921da177e4SLinus Torvalds } 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds static ssize_t 951da177e4SLinus Torvalds bus_attr_store(struct kobject * kobj, struct attribute * attr, 961da177e4SLinus Torvalds const char * buf, size_t count) 971da177e4SLinus Torvalds { 981da177e4SLinus Torvalds struct bus_attribute * bus_attr = to_bus_attr(attr); 991da177e4SLinus Torvalds struct bus_type * bus = to_bus(kobj); 1001da177e4SLinus Torvalds ssize_t ret = 0; 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds if (bus_attr->store) 1031da177e4SLinus Torvalds ret = bus_attr->store(bus, buf, count); 1041da177e4SLinus Torvalds return ret; 1051da177e4SLinus Torvalds } 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds static struct sysfs_ops bus_sysfs_ops = { 1081da177e4SLinus Torvalds .show = bus_attr_show, 1091da177e4SLinus Torvalds .store = bus_attr_store, 1101da177e4SLinus Torvalds }; 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) 1131da177e4SLinus Torvalds { 1141da177e4SLinus Torvalds int error; 1151da177e4SLinus Torvalds if (get_bus(bus)) { 1161da177e4SLinus Torvalds error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr); 1171da177e4SLinus Torvalds put_bus(bus); 1181da177e4SLinus Torvalds } else 1191da177e4SLinus Torvalds error = -EINVAL; 1201da177e4SLinus Torvalds return error; 1211da177e4SLinus Torvalds } 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) 1241da177e4SLinus Torvalds { 1251da177e4SLinus Torvalds if (get_bus(bus)) { 1261da177e4SLinus Torvalds sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr); 1271da177e4SLinus Torvalds put_bus(bus); 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds } 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds static struct kobj_type ktype_bus = { 1321da177e4SLinus Torvalds .sysfs_ops = &bus_sysfs_ops, 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds }; 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds decl_subsys(bus, &ktype_bus, NULL); 1371da177e4SLinus Torvalds 1381da177e4SLinus Torvalds static int __bus_for_each_dev(struct bus_type *bus, struct device *start, 1391da177e4SLinus Torvalds void *data, int (*fn)(struct device *, void *)) 1401da177e4SLinus Torvalds { 1411da177e4SLinus Torvalds struct list_head *head; 1421da177e4SLinus Torvalds struct device *dev; 1431da177e4SLinus Torvalds int error = 0; 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds if (!(bus = get_bus(bus))) 1461da177e4SLinus Torvalds return -EINVAL; 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds head = &bus->devices.list; 1491da177e4SLinus Torvalds dev = list_prepare_entry(start, head, bus_list); 1501da177e4SLinus Torvalds list_for_each_entry_continue(dev, head, bus_list) { 1511da177e4SLinus Torvalds get_device(dev); 1521da177e4SLinus Torvalds error = fn(dev, data); 1531da177e4SLinus Torvalds put_device(dev); 1541da177e4SLinus Torvalds if (error) 1551da177e4SLinus Torvalds break; 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds put_bus(bus); 1581da177e4SLinus Torvalds return error; 1591da177e4SLinus Torvalds } 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start, 1621da177e4SLinus Torvalds void * data, int (*fn)(struct device_driver *, void *)) 1631da177e4SLinus Torvalds { 1641da177e4SLinus Torvalds struct list_head *head; 1651da177e4SLinus Torvalds struct device_driver *drv; 1661da177e4SLinus Torvalds int error = 0; 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds if (!(bus = get_bus(bus))) 1691da177e4SLinus Torvalds return -EINVAL; 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds head = &bus->drivers.list; 1721da177e4SLinus Torvalds drv = list_prepare_entry(start, head, kobj.entry); 1731da177e4SLinus Torvalds list_for_each_entry_continue(drv, head, kobj.entry) { 1741da177e4SLinus Torvalds get_driver(drv); 1751da177e4SLinus Torvalds error = fn(drv, data); 1761da177e4SLinus Torvalds put_driver(drv); 1771da177e4SLinus Torvalds if (error) 1781da177e4SLinus Torvalds break; 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds put_bus(bus); 1811da177e4SLinus Torvalds return error; 1821da177e4SLinus Torvalds } 1831da177e4SLinus Torvalds 1841da177e4SLinus Torvalds /** 1851da177e4SLinus Torvalds * bus_for_each_dev - device iterator. 1861da177e4SLinus Torvalds * @bus: bus type. 1871da177e4SLinus Torvalds * @start: device to start iterating from. 1881da177e4SLinus Torvalds * @data: data for the callback. 1891da177e4SLinus Torvalds * @fn: function to be called for each device. 1901da177e4SLinus Torvalds * 1911da177e4SLinus Torvalds * Iterate over @bus's list of devices, and call @fn for each, 1921da177e4SLinus Torvalds * passing it @data. If @start is not NULL, we use that device to 1931da177e4SLinus Torvalds * begin iterating from. 1941da177e4SLinus Torvalds * 1951da177e4SLinus Torvalds * We check the return of @fn each time. If it returns anything 1961da177e4SLinus Torvalds * other than 0, we break out and return that value. 1971da177e4SLinus Torvalds * 1981da177e4SLinus Torvalds * NOTE: The device that returns a non-zero value is not retained 1991da177e4SLinus Torvalds * in any way, nor is its refcount incremented. If the caller needs 2001da177e4SLinus Torvalds * to retain this data, it should do, and increment the reference 2011da177e4SLinus Torvalds * count in the supplied callback. 2021da177e4SLinus Torvalds */ 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds int bus_for_each_dev(struct bus_type * bus, struct device * start, 2051da177e4SLinus Torvalds void * data, int (*fn)(struct device *, void *)) 2061da177e4SLinus Torvalds { 2071da177e4SLinus Torvalds int ret; 2081da177e4SLinus Torvalds 2091da177e4SLinus Torvalds down_read(&bus->subsys.rwsem); 2101da177e4SLinus Torvalds ret = __bus_for_each_dev(bus, start, data, fn); 2111da177e4SLinus Torvalds up_read(&bus->subsys.rwsem); 2121da177e4SLinus Torvalds return ret; 2131da177e4SLinus Torvalds } 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds /** 2161da177e4SLinus Torvalds * bus_for_each_drv - driver iterator 2171da177e4SLinus Torvalds * @bus: bus we're dealing with. 2181da177e4SLinus Torvalds * @start: driver to start iterating on. 2191da177e4SLinus Torvalds * @data: data to pass to the callback. 2201da177e4SLinus Torvalds * @fn: function to call for each driver. 2211da177e4SLinus Torvalds * 2221da177e4SLinus Torvalds * This is nearly identical to the device iterator above. 2231da177e4SLinus Torvalds * We iterate over each driver that belongs to @bus, and call 2241da177e4SLinus Torvalds * @fn for each. If @fn returns anything but 0, we break out 2251da177e4SLinus Torvalds * and return it. If @start is not NULL, we use it as the head 2261da177e4SLinus Torvalds * of the list. 2271da177e4SLinus Torvalds * 2281da177e4SLinus Torvalds * NOTE: we don't return the driver that returns a non-zero 2291da177e4SLinus Torvalds * value, nor do we leave the reference count incremented for that 2301da177e4SLinus Torvalds * driver. If the caller needs to know that info, it must set it 2311da177e4SLinus Torvalds * in the callback. It must also be sure to increment the refcount 2321da177e4SLinus Torvalds * so it doesn't disappear before returning to the caller. 2331da177e4SLinus Torvalds */ 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 2361da177e4SLinus Torvalds void * data, int (*fn)(struct device_driver *, void *)) 2371da177e4SLinus Torvalds { 2381da177e4SLinus Torvalds int ret; 2391da177e4SLinus Torvalds 2401da177e4SLinus Torvalds down_read(&bus->subsys.rwsem); 2411da177e4SLinus Torvalds ret = __bus_for_each_drv(bus, start, data, fn); 2421da177e4SLinus Torvalds up_read(&bus->subsys.rwsem); 2431da177e4SLinus Torvalds return ret; 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds /** 2471da177e4SLinus Torvalds * device_bind_driver - bind a driver to one device. 2481da177e4SLinus Torvalds * @dev: device. 2491da177e4SLinus Torvalds * 2501da177e4SLinus Torvalds * Allow manual attachment of a driver to a device. 2511da177e4SLinus Torvalds * Caller must have already set @dev->driver. 2521da177e4SLinus Torvalds * 2531da177e4SLinus Torvalds * Note that this does not modify the bus reference count 2541da177e4SLinus Torvalds * nor take the bus's rwsem. Please verify those are accounted 2551da177e4SLinus Torvalds * for before calling this. (It is ok to call with no other effort 2561da177e4SLinus Torvalds * from a driver's probe() method.) 2571da177e4SLinus Torvalds */ 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds void device_bind_driver(struct device * dev) 2601da177e4SLinus Torvalds { 2611da177e4SLinus Torvalds pr_debug("bound device '%s' to driver '%s'\n", 2621da177e4SLinus Torvalds dev->bus_id, dev->driver->name); 2631da177e4SLinus Torvalds list_add_tail(&dev->driver_list, &dev->driver->devices); 2641da177e4SLinus Torvalds sysfs_create_link(&dev->driver->kobj, &dev->kobj, 2651da177e4SLinus Torvalds kobject_name(&dev->kobj)); 2661da177e4SLinus Torvalds sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); 2671da177e4SLinus Torvalds } 2681da177e4SLinus Torvalds 2691da177e4SLinus Torvalds 2701da177e4SLinus Torvalds /** 2711da177e4SLinus Torvalds * driver_probe_device - attempt to bind device & driver. 2721da177e4SLinus Torvalds * @drv: driver. 2731da177e4SLinus Torvalds * @dev: device. 2741da177e4SLinus Torvalds * 2751da177e4SLinus Torvalds * First, we call the bus's match function, if one present, which 2761da177e4SLinus Torvalds * should compare the device IDs the driver supports with the 2771da177e4SLinus Torvalds * device IDs of the device. Note we don't do this ourselves 2781da177e4SLinus Torvalds * because we don't know the format of the ID structures, nor what 2791da177e4SLinus Torvalds * is to be considered a match and what is not. 2801da177e4SLinus Torvalds * 2811da177e4SLinus Torvalds * If we find a match, we call @drv->probe(@dev) if it exists, and 2821da177e4SLinus Torvalds * call device_bind_driver() above. 2831da177e4SLinus Torvalds */ 2841da177e4SLinus Torvalds int driver_probe_device(struct device_driver * drv, struct device * dev) 2851da177e4SLinus Torvalds { 2861da177e4SLinus Torvalds if (drv->bus->match && !drv->bus->match(dev, drv)) 2871da177e4SLinus Torvalds return -ENODEV; 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds dev->driver = drv; 2901da177e4SLinus Torvalds if (drv->probe) { 2911da177e4SLinus Torvalds int error = drv->probe(dev); 2921da177e4SLinus Torvalds if (error) { 2931da177e4SLinus Torvalds dev->driver = NULL; 2941da177e4SLinus Torvalds return error; 2951da177e4SLinus Torvalds } 2961da177e4SLinus Torvalds } 2971da177e4SLinus Torvalds 2981da177e4SLinus Torvalds device_bind_driver(dev); 2991da177e4SLinus Torvalds return 0; 3001da177e4SLinus Torvalds } 3011da177e4SLinus Torvalds 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds /** 3041da177e4SLinus Torvalds * device_attach - try to attach device to a driver. 3051da177e4SLinus Torvalds * @dev: device. 3061da177e4SLinus Torvalds * 3071da177e4SLinus Torvalds * Walk the list of drivers that the bus has and call 3081da177e4SLinus Torvalds * driver_probe_device() for each pair. If a compatible 3091da177e4SLinus Torvalds * pair is found, break out and return. 3101da177e4SLinus Torvalds */ 3111da177e4SLinus Torvalds int device_attach(struct device * dev) 3121da177e4SLinus Torvalds { 3131da177e4SLinus Torvalds struct bus_type * bus = dev->bus; 3141da177e4SLinus Torvalds struct list_head * entry; 3151da177e4SLinus Torvalds int error; 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds if (dev->driver) { 3181da177e4SLinus Torvalds device_bind_driver(dev); 3191da177e4SLinus Torvalds return 1; 3201da177e4SLinus Torvalds } 3211da177e4SLinus Torvalds 3221da177e4SLinus Torvalds if (bus->match) { 3231da177e4SLinus Torvalds list_for_each(entry, &bus->drivers.list) { 3241da177e4SLinus Torvalds struct device_driver * drv = to_drv(entry); 3251da177e4SLinus Torvalds error = driver_probe_device(drv, dev); 3261da177e4SLinus Torvalds if (!error) 3271da177e4SLinus Torvalds /* success, driver matched */ 3281da177e4SLinus Torvalds return 1; 3291da177e4SLinus Torvalds if (error != -ENODEV && error != -ENXIO) 3301da177e4SLinus Torvalds /* driver matched but the probe failed */ 3311da177e4SLinus Torvalds printk(KERN_WARNING 3321da177e4SLinus Torvalds "%s: probe of %s failed with error %d\n", 3331da177e4SLinus Torvalds drv->name, dev->bus_id, error); 3341da177e4SLinus Torvalds } 3351da177e4SLinus Torvalds } 3361da177e4SLinus Torvalds 3371da177e4SLinus Torvalds return 0; 3381da177e4SLinus Torvalds } 3391da177e4SLinus Torvalds 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds /** 3421da177e4SLinus Torvalds * driver_attach - try to bind driver to devices. 3431da177e4SLinus Torvalds * @drv: driver. 3441da177e4SLinus Torvalds * 3451da177e4SLinus Torvalds * Walk the list of devices that the bus has on it and try to 3461da177e4SLinus Torvalds * match the driver with each one. If driver_probe_device() 3471da177e4SLinus Torvalds * returns 0 and the @dev->driver is set, we've found a 3481da177e4SLinus Torvalds * compatible pair. 3491da177e4SLinus Torvalds * 3501da177e4SLinus Torvalds * Note that we ignore the -ENODEV error from driver_probe_device(), 3511da177e4SLinus Torvalds * since it's perfectly valid for a driver not to bind to any devices. 3521da177e4SLinus Torvalds */ 3531da177e4SLinus Torvalds void driver_attach(struct device_driver * drv) 3541da177e4SLinus Torvalds { 3551da177e4SLinus Torvalds struct bus_type * bus = drv->bus; 3561da177e4SLinus Torvalds struct list_head * entry; 3571da177e4SLinus Torvalds int error; 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds if (!bus->match) 3601da177e4SLinus Torvalds return; 3611da177e4SLinus Torvalds 3621da177e4SLinus Torvalds list_for_each(entry, &bus->devices.list) { 3631da177e4SLinus Torvalds struct device * dev = container_of(entry, struct device, bus_list); 3641da177e4SLinus Torvalds if (!dev->driver) { 3651da177e4SLinus Torvalds error = driver_probe_device(drv, dev); 3661da177e4SLinus Torvalds if (error && (error != -ENODEV)) 3671da177e4SLinus Torvalds /* driver matched but the probe failed */ 3681da177e4SLinus Torvalds printk(KERN_WARNING 3691da177e4SLinus Torvalds "%s: probe of %s failed with error %d\n", 3701da177e4SLinus Torvalds drv->name, dev->bus_id, error); 3711da177e4SLinus Torvalds } 3721da177e4SLinus Torvalds } 3731da177e4SLinus Torvalds } 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds 3761da177e4SLinus Torvalds /** 3771da177e4SLinus Torvalds * device_release_driver - manually detach device from driver. 3781da177e4SLinus Torvalds * @dev: device. 3791da177e4SLinus Torvalds * 3801da177e4SLinus Torvalds * Manually detach device from driver. 3811da177e4SLinus Torvalds * Note that this is called without incrementing the bus 3821da177e4SLinus Torvalds * reference count nor taking the bus's rwsem. Be sure that 3831da177e4SLinus Torvalds * those are accounted for before calling this function. 3841da177e4SLinus Torvalds */ 3851da177e4SLinus Torvalds 3861da177e4SLinus Torvalds void device_release_driver(struct device * dev) 3871da177e4SLinus Torvalds { 3881da177e4SLinus Torvalds struct device_driver * drv = dev->driver; 3891da177e4SLinus Torvalds if (drv) { 3901da177e4SLinus Torvalds sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); 3911da177e4SLinus Torvalds sysfs_remove_link(&dev->kobj, "driver"); 3921da177e4SLinus Torvalds list_del_init(&dev->driver_list); 3931da177e4SLinus Torvalds if (drv->remove) 3941da177e4SLinus Torvalds drv->remove(dev); 3951da177e4SLinus Torvalds dev->driver = NULL; 3961da177e4SLinus Torvalds } 3971da177e4SLinus Torvalds } 3981da177e4SLinus Torvalds 3991da177e4SLinus Torvalds 4001da177e4SLinus Torvalds /** 4011da177e4SLinus Torvalds * driver_detach - detach driver from all devices it controls. 4021da177e4SLinus Torvalds * @drv: driver. 4031da177e4SLinus Torvalds */ 4041da177e4SLinus Torvalds 4051da177e4SLinus Torvalds static void driver_detach(struct device_driver * drv) 4061da177e4SLinus Torvalds { 407b2d84f07SRoman Kagan while (!list_empty(&drv->devices)) { 408b2d84f07SRoman Kagan struct device * dev = container_of(drv->devices.next, struct device, driver_list); 4091da177e4SLinus Torvalds device_release_driver(dev); 4101da177e4SLinus Torvalds } 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds 4131da177e4SLinus Torvalds static int device_add_attrs(struct bus_type * bus, struct device * dev) 4141da177e4SLinus Torvalds { 4151da177e4SLinus Torvalds int error = 0; 4161da177e4SLinus Torvalds int i; 4171da177e4SLinus Torvalds 4181da177e4SLinus Torvalds if (bus->dev_attrs) { 4191da177e4SLinus Torvalds for (i = 0; attr_name(bus->dev_attrs[i]); i++) { 4201da177e4SLinus Torvalds error = device_create_file(dev,&bus->dev_attrs[i]); 4211da177e4SLinus Torvalds if (error) 4221da177e4SLinus Torvalds goto Err; 4231da177e4SLinus Torvalds } 4241da177e4SLinus Torvalds } 4251da177e4SLinus Torvalds Done: 4261da177e4SLinus Torvalds return error; 4271da177e4SLinus Torvalds Err: 4281da177e4SLinus Torvalds while (--i >= 0) 4291da177e4SLinus Torvalds device_remove_file(dev,&bus->dev_attrs[i]); 4301da177e4SLinus Torvalds goto Done; 4311da177e4SLinus Torvalds } 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvalds 4341da177e4SLinus Torvalds static void device_remove_attrs(struct bus_type * bus, struct device * dev) 4351da177e4SLinus Torvalds { 4361da177e4SLinus Torvalds int i; 4371da177e4SLinus Torvalds 4381da177e4SLinus Torvalds if (bus->dev_attrs) { 4391da177e4SLinus Torvalds for (i = 0; attr_name(bus->dev_attrs[i]); i++) 4401da177e4SLinus Torvalds device_remove_file(dev,&bus->dev_attrs[i]); 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds } 4431da177e4SLinus Torvalds 4441da177e4SLinus Torvalds 4451da177e4SLinus Torvalds /** 4461da177e4SLinus Torvalds * bus_add_device - add device to bus 4471da177e4SLinus Torvalds * @dev: device being added 4481da177e4SLinus Torvalds * 4491da177e4SLinus Torvalds * - Add the device to its bus's list of devices. 4501da177e4SLinus Torvalds * - Try to attach to driver. 4511da177e4SLinus Torvalds * - Create link to device's physical location. 4521da177e4SLinus Torvalds */ 4531da177e4SLinus Torvalds int bus_add_device(struct device * dev) 4541da177e4SLinus Torvalds { 4551da177e4SLinus Torvalds struct bus_type * bus = get_bus(dev->bus); 4561da177e4SLinus Torvalds int error = 0; 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds if (bus) { 4591da177e4SLinus Torvalds down_write(&dev->bus->subsys.rwsem); 4601da177e4SLinus Torvalds pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); 4611da177e4SLinus Torvalds list_add_tail(&dev->bus_list, &dev->bus->devices.list); 4621da177e4SLinus Torvalds device_attach(dev); 4631da177e4SLinus Torvalds up_write(&dev->bus->subsys.rwsem); 4641da177e4SLinus Torvalds device_add_attrs(bus, dev); 4651da177e4SLinus Torvalds sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 4661da177e4SLinus Torvalds sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); 4671da177e4SLinus Torvalds } 4681da177e4SLinus Torvalds return error; 4691da177e4SLinus Torvalds } 4701da177e4SLinus Torvalds 4711da177e4SLinus Torvalds /** 4721da177e4SLinus Torvalds * bus_remove_device - remove device from bus 4731da177e4SLinus Torvalds * @dev: device to be removed 4741da177e4SLinus Torvalds * 4751da177e4SLinus Torvalds * - Remove symlink from bus's directory. 4761da177e4SLinus Torvalds * - Delete device from bus's list. 4771da177e4SLinus Torvalds * - Detach from its driver. 4781da177e4SLinus Torvalds * - Drop reference taken in bus_add_device(). 4791da177e4SLinus Torvalds */ 4801da177e4SLinus Torvalds void bus_remove_device(struct device * dev) 4811da177e4SLinus Torvalds { 4821da177e4SLinus Torvalds if (dev->bus) { 4831da177e4SLinus Torvalds sysfs_remove_link(&dev->kobj, "bus"); 4841da177e4SLinus Torvalds sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); 4851da177e4SLinus Torvalds device_remove_attrs(dev->bus, dev); 4861da177e4SLinus Torvalds down_write(&dev->bus->subsys.rwsem); 4871da177e4SLinus Torvalds pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); 4881da177e4SLinus Torvalds device_release_driver(dev); 4891da177e4SLinus Torvalds list_del_init(&dev->bus_list); 4901da177e4SLinus Torvalds up_write(&dev->bus->subsys.rwsem); 4911da177e4SLinus Torvalds put_bus(dev->bus); 4921da177e4SLinus Torvalds } 4931da177e4SLinus Torvalds } 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) 4961da177e4SLinus Torvalds { 4971da177e4SLinus Torvalds int error = 0; 4981da177e4SLinus Torvalds int i; 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds if (bus->drv_attrs) { 5011da177e4SLinus Torvalds for (i = 0; attr_name(bus->drv_attrs[i]); i++) { 5021da177e4SLinus Torvalds error = driver_create_file(drv, &bus->drv_attrs[i]); 5031da177e4SLinus Torvalds if (error) 5041da177e4SLinus Torvalds goto Err; 5051da177e4SLinus Torvalds } 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds Done: 5081da177e4SLinus Torvalds return error; 5091da177e4SLinus Torvalds Err: 5101da177e4SLinus Torvalds while (--i >= 0) 5111da177e4SLinus Torvalds driver_remove_file(drv, &bus->drv_attrs[i]); 5121da177e4SLinus Torvalds goto Done; 5131da177e4SLinus Torvalds } 5141da177e4SLinus Torvalds 5151da177e4SLinus Torvalds 5161da177e4SLinus Torvalds static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv) 5171da177e4SLinus Torvalds { 5181da177e4SLinus Torvalds int i; 5191da177e4SLinus Torvalds 5201da177e4SLinus Torvalds if (bus->drv_attrs) { 5211da177e4SLinus Torvalds for (i = 0; attr_name(bus->drv_attrs[i]); i++) 5221da177e4SLinus Torvalds driver_remove_file(drv, &bus->drv_attrs[i]); 5231da177e4SLinus Torvalds } 5241da177e4SLinus Torvalds } 5251da177e4SLinus Torvalds 5261da177e4SLinus Torvalds 5271da177e4SLinus Torvalds /** 5281da177e4SLinus Torvalds * bus_add_driver - Add a driver to the bus. 5291da177e4SLinus Torvalds * @drv: driver. 5301da177e4SLinus Torvalds * 5311da177e4SLinus Torvalds */ 5321da177e4SLinus Torvalds int bus_add_driver(struct device_driver * drv) 5331da177e4SLinus Torvalds { 5341da177e4SLinus Torvalds struct bus_type * bus = get_bus(drv->bus); 5351da177e4SLinus Torvalds int error = 0; 5361da177e4SLinus Torvalds 5371da177e4SLinus Torvalds if (bus) { 5381da177e4SLinus Torvalds pr_debug("bus %s: add driver %s\n", bus->name, drv->name); 5391da177e4SLinus Torvalds error = kobject_set_name(&drv->kobj, "%s", drv->name); 5401da177e4SLinus Torvalds if (error) { 5411da177e4SLinus Torvalds put_bus(bus); 5421da177e4SLinus Torvalds return error; 5431da177e4SLinus Torvalds } 5441da177e4SLinus Torvalds drv->kobj.kset = &bus->drivers; 5451da177e4SLinus Torvalds if ((error = kobject_register(&drv->kobj))) { 5461da177e4SLinus Torvalds put_bus(bus); 5471da177e4SLinus Torvalds return error; 5481da177e4SLinus Torvalds } 5491da177e4SLinus Torvalds 5501da177e4SLinus Torvalds down_write(&bus->subsys.rwsem); 5511da177e4SLinus Torvalds driver_attach(drv); 5521da177e4SLinus Torvalds up_write(&bus->subsys.rwsem); 5531da177e4SLinus Torvalds module_add_driver(drv->owner, drv); 5541da177e4SLinus Torvalds 5551da177e4SLinus Torvalds driver_add_attrs(bus, drv); 5561da177e4SLinus Torvalds } 5571da177e4SLinus Torvalds return error; 5581da177e4SLinus Torvalds } 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds 5611da177e4SLinus Torvalds /** 5621da177e4SLinus Torvalds * bus_remove_driver - delete driver from bus's knowledge. 5631da177e4SLinus Torvalds * @drv: driver. 5641da177e4SLinus Torvalds * 5651da177e4SLinus Torvalds * Detach the driver from the devices it controls, and remove 5661da177e4SLinus Torvalds * it from its bus's list of drivers. Finally, we drop the reference 5671da177e4SLinus Torvalds * to the bus we took in bus_add_driver(). 5681da177e4SLinus Torvalds */ 5691da177e4SLinus Torvalds 5701da177e4SLinus Torvalds void bus_remove_driver(struct device_driver * drv) 5711da177e4SLinus Torvalds { 5721da177e4SLinus Torvalds if (drv->bus) { 5731da177e4SLinus Torvalds driver_remove_attrs(drv->bus, drv); 5741da177e4SLinus Torvalds down_write(&drv->bus->subsys.rwsem); 5751da177e4SLinus Torvalds pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 5761da177e4SLinus Torvalds driver_detach(drv); 5771da177e4SLinus Torvalds up_write(&drv->bus->subsys.rwsem); 5781da177e4SLinus Torvalds module_remove_driver(drv); 5791da177e4SLinus Torvalds kobject_unregister(&drv->kobj); 5801da177e4SLinus Torvalds put_bus(drv->bus); 5811da177e4SLinus Torvalds } 5821da177e4SLinus Torvalds } 5831da177e4SLinus Torvalds 5841da177e4SLinus Torvalds 5851da177e4SLinus Torvalds /* Helper for bus_rescan_devices's iter */ 5861da177e4SLinus Torvalds static int bus_rescan_devices_helper(struct device *dev, void *data) 5871da177e4SLinus Torvalds { 5881da177e4SLinus Torvalds int *count = data; 5891da177e4SLinus Torvalds 5901da177e4SLinus Torvalds if (!dev->driver && device_attach(dev)) 5911da177e4SLinus Torvalds (*count)++; 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds return 0; 5941da177e4SLinus Torvalds } 5951da177e4SLinus Torvalds 5961da177e4SLinus Torvalds 5971da177e4SLinus Torvalds /** 5981da177e4SLinus Torvalds * bus_rescan_devices - rescan devices on the bus for possible drivers 5991da177e4SLinus Torvalds * @bus: the bus to scan. 6001da177e4SLinus Torvalds * 6011da177e4SLinus Torvalds * This function will look for devices on the bus with no driver 6021da177e4SLinus Torvalds * attached and rescan it against existing drivers to see if it 6031da177e4SLinus Torvalds * matches any. Calls device_attach(). Returns the number of devices 6041da177e4SLinus Torvalds * that were sucessfully bound to a driver. 6051da177e4SLinus Torvalds */ 6061da177e4SLinus Torvalds int bus_rescan_devices(struct bus_type * bus) 6071da177e4SLinus Torvalds { 6081da177e4SLinus Torvalds int count = 0; 6091da177e4SLinus Torvalds 6101da177e4SLinus Torvalds down_write(&bus->subsys.rwsem); 6111da177e4SLinus Torvalds __bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); 6121da177e4SLinus Torvalds up_write(&bus->subsys.rwsem); 6131da177e4SLinus Torvalds 6141da177e4SLinus Torvalds return count; 6151da177e4SLinus Torvalds } 6161da177e4SLinus Torvalds 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds struct bus_type * get_bus(struct bus_type * bus) 6191da177e4SLinus Torvalds { 6201da177e4SLinus Torvalds return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL; 6211da177e4SLinus Torvalds } 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds void put_bus(struct bus_type * bus) 6241da177e4SLinus Torvalds { 6251da177e4SLinus Torvalds subsys_put(&bus->subsys); 6261da177e4SLinus Torvalds } 6271da177e4SLinus Torvalds 6281da177e4SLinus Torvalds 6291da177e4SLinus Torvalds /** 6301da177e4SLinus Torvalds * find_bus - locate bus by name. 6311da177e4SLinus Torvalds * @name: name of bus. 6321da177e4SLinus Torvalds * 6331da177e4SLinus Torvalds * Call kset_find_obj() to iterate over list of buses to 6341da177e4SLinus Torvalds * find a bus by name. Return bus if found. 6351da177e4SLinus Torvalds * 6361da177e4SLinus Torvalds * Note that kset_find_obj increments bus' reference count. 6371da177e4SLinus Torvalds */ 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds struct bus_type * find_bus(char * name) 6401da177e4SLinus Torvalds { 6411da177e4SLinus Torvalds struct kobject * k = kset_find_obj(&bus_subsys.kset, name); 6421da177e4SLinus Torvalds return k ? to_bus(k) : NULL; 6431da177e4SLinus Torvalds } 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds 6461da177e4SLinus Torvalds /** 6471da177e4SLinus Torvalds * bus_add_attrs - Add default attributes for this bus. 6481da177e4SLinus Torvalds * @bus: Bus that has just been registered. 6491da177e4SLinus Torvalds */ 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds static int bus_add_attrs(struct bus_type * bus) 6521da177e4SLinus Torvalds { 6531da177e4SLinus Torvalds int error = 0; 6541da177e4SLinus Torvalds int i; 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds if (bus->bus_attrs) { 6571da177e4SLinus Torvalds for (i = 0; attr_name(bus->bus_attrs[i]); i++) { 6581da177e4SLinus Torvalds if ((error = bus_create_file(bus,&bus->bus_attrs[i]))) 6591da177e4SLinus Torvalds goto Err; 6601da177e4SLinus Torvalds } 6611da177e4SLinus Torvalds } 6621da177e4SLinus Torvalds Done: 6631da177e4SLinus Torvalds return error; 6641da177e4SLinus Torvalds Err: 6651da177e4SLinus Torvalds while (--i >= 0) 6661da177e4SLinus Torvalds bus_remove_file(bus,&bus->bus_attrs[i]); 6671da177e4SLinus Torvalds goto Done; 6681da177e4SLinus Torvalds } 6691da177e4SLinus Torvalds 6701da177e4SLinus Torvalds static void bus_remove_attrs(struct bus_type * bus) 6711da177e4SLinus Torvalds { 6721da177e4SLinus Torvalds int i; 6731da177e4SLinus Torvalds 6741da177e4SLinus Torvalds if (bus->bus_attrs) { 6751da177e4SLinus Torvalds for (i = 0; attr_name(bus->bus_attrs[i]); i++) 6761da177e4SLinus Torvalds bus_remove_file(bus,&bus->bus_attrs[i]); 6771da177e4SLinus Torvalds } 6781da177e4SLinus Torvalds } 6791da177e4SLinus Torvalds 6801da177e4SLinus Torvalds /** 6811da177e4SLinus Torvalds * bus_register - register a bus with the system. 6821da177e4SLinus Torvalds * @bus: bus. 6831da177e4SLinus Torvalds * 6841da177e4SLinus Torvalds * Once we have that, we registered the bus with the kobject 6851da177e4SLinus Torvalds * infrastructure, then register the children subsystems it has: 6861da177e4SLinus Torvalds * the devices and drivers that belong to the bus. 6871da177e4SLinus Torvalds */ 6881da177e4SLinus Torvalds int bus_register(struct bus_type * bus) 6891da177e4SLinus Torvalds { 6901da177e4SLinus Torvalds int retval; 6911da177e4SLinus Torvalds 6921da177e4SLinus Torvalds retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); 6931da177e4SLinus Torvalds if (retval) 6941da177e4SLinus Torvalds goto out; 6951da177e4SLinus Torvalds 6961da177e4SLinus Torvalds subsys_set_kset(bus, bus_subsys); 6971da177e4SLinus Torvalds retval = subsystem_register(&bus->subsys); 6981da177e4SLinus Torvalds if (retval) 6991da177e4SLinus Torvalds goto out; 7001da177e4SLinus Torvalds 7011da177e4SLinus Torvalds kobject_set_name(&bus->devices.kobj, "devices"); 7021da177e4SLinus Torvalds bus->devices.subsys = &bus->subsys; 7031da177e4SLinus Torvalds retval = kset_register(&bus->devices); 7041da177e4SLinus Torvalds if (retval) 7051da177e4SLinus Torvalds goto bus_devices_fail; 7061da177e4SLinus Torvalds 7071da177e4SLinus Torvalds kobject_set_name(&bus->drivers.kobj, "drivers"); 7081da177e4SLinus Torvalds bus->drivers.subsys = &bus->subsys; 7091da177e4SLinus Torvalds bus->drivers.ktype = &ktype_driver; 7101da177e4SLinus Torvalds retval = kset_register(&bus->drivers); 7111da177e4SLinus Torvalds if (retval) 7121da177e4SLinus Torvalds goto bus_drivers_fail; 7131da177e4SLinus Torvalds bus_add_attrs(bus); 7141da177e4SLinus Torvalds 7151da177e4SLinus Torvalds pr_debug("bus type '%s' registered\n", bus->name); 7161da177e4SLinus Torvalds return 0; 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds bus_drivers_fail: 7191da177e4SLinus Torvalds kset_unregister(&bus->devices); 7201da177e4SLinus Torvalds bus_devices_fail: 7211da177e4SLinus Torvalds subsystem_unregister(&bus->subsys); 7221da177e4SLinus Torvalds out: 7231da177e4SLinus Torvalds return retval; 7241da177e4SLinus Torvalds } 7251da177e4SLinus Torvalds 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds /** 7281da177e4SLinus Torvalds * bus_unregister - remove a bus from the system 7291da177e4SLinus Torvalds * @bus: bus. 7301da177e4SLinus Torvalds * 7311da177e4SLinus Torvalds * Unregister the child subsystems and the bus itself. 7321da177e4SLinus Torvalds * Finally, we call put_bus() to release the refcount 7331da177e4SLinus Torvalds */ 7341da177e4SLinus Torvalds void bus_unregister(struct bus_type * bus) 7351da177e4SLinus Torvalds { 7361da177e4SLinus Torvalds pr_debug("bus %s: unregistering\n", bus->name); 7371da177e4SLinus Torvalds bus_remove_attrs(bus); 7381da177e4SLinus Torvalds kset_unregister(&bus->drivers); 7391da177e4SLinus Torvalds kset_unregister(&bus->devices); 7401da177e4SLinus Torvalds subsystem_unregister(&bus->subsys); 7411da177e4SLinus Torvalds } 7421da177e4SLinus Torvalds 7431da177e4SLinus Torvalds int __init buses_init(void) 7441da177e4SLinus Torvalds { 7451da177e4SLinus Torvalds return subsystem_register(&bus_subsys); 7461da177e4SLinus Torvalds } 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds 7491da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_for_each_dev); 7501da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_for_each_drv); 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(driver_probe_device); 7531da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(device_bind_driver); 7541da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(device_release_driver); 7551da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(device_attach); 7561da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(driver_attach); 7571da177e4SLinus Torvalds 7581da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_add_device); 7591da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_remove_device); 7601da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_register); 7611da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_unregister); 7621da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_rescan_devices); 7631da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(get_bus); 7641da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(put_bus); 7651da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(find_bus); 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_create_file); 7681da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_remove_file); 769