xref: /linux/drivers/base/bus.c (revision b8c5cec23d5c33b767a1cddebd4f8813a9563e3c)
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/device.h>
121da177e4SLinus Torvalds #include <linux/module.h>
131da177e4SLinus Torvalds #include <linux/errno.h>
141da177e4SLinus Torvalds #include <linux/init.h>
151da177e4SLinus Torvalds #include <linux/string.h>
161da177e4SLinus Torvalds #include "base.h"
171da177e4SLinus Torvalds #include "power/power.h"
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
201da177e4SLinus Torvalds #define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds /*
231da177e4SLinus Torvalds  * sysfs bindings for drivers
241da177e4SLinus Torvalds  */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
271da177e4SLinus Torvalds #define to_driver(obj) container_of(obj, struct device_driver, kobj)
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds 
30*b8c5cec2SKay Sievers static int __must_check bus_rescan_devices_helper(struct device *dev,
31*b8c5cec2SKay Sievers 						void *data);
32*b8c5cec2SKay Sievers 
331da177e4SLinus Torvalds static ssize_t
341da177e4SLinus Torvalds drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
351da177e4SLinus Torvalds {
361da177e4SLinus Torvalds 	struct driver_attribute * drv_attr = to_drv_attr(attr);
371da177e4SLinus Torvalds 	struct device_driver * drv = to_driver(kobj);
384a0c20bfSDmitry Torokhov 	ssize_t ret = -EIO;
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds 	if (drv_attr->show)
411da177e4SLinus Torvalds 		ret = drv_attr->show(drv, buf);
421da177e4SLinus Torvalds 	return ret;
431da177e4SLinus Torvalds }
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds static ssize_t
461da177e4SLinus Torvalds drv_attr_store(struct kobject * kobj, struct attribute * attr,
471da177e4SLinus Torvalds 	       const char * buf, size_t count)
481da177e4SLinus Torvalds {
491da177e4SLinus Torvalds 	struct driver_attribute * drv_attr = to_drv_attr(attr);
501da177e4SLinus Torvalds 	struct device_driver * drv = to_driver(kobj);
514a0c20bfSDmitry Torokhov 	ssize_t ret = -EIO;
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds 	if (drv_attr->store)
541da177e4SLinus Torvalds 		ret = drv_attr->store(drv, buf, count);
551da177e4SLinus Torvalds 	return ret;
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds static struct sysfs_ops driver_sysfs_ops = {
591da177e4SLinus Torvalds 	.show	= drv_attr_show,
601da177e4SLinus Torvalds 	.store	= drv_attr_store,
611da177e4SLinus Torvalds };
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds static void driver_release(struct kobject * kobj)
651da177e4SLinus Torvalds {
661da177e4SLinus Torvalds 	struct device_driver * drv = to_driver(kobj);
671da177e4SLinus Torvalds 	complete(&drv->unloaded);
681da177e4SLinus Torvalds }
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds static struct kobj_type ktype_driver = {
711da177e4SLinus Torvalds 	.sysfs_ops	= &driver_sysfs_ops,
721da177e4SLinus Torvalds 	.release	= driver_release,
731da177e4SLinus Torvalds };
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds /*
771da177e4SLinus Torvalds  * sysfs bindings for buses
781da177e4SLinus Torvalds  */
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds static ssize_t
821da177e4SLinus Torvalds bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
831da177e4SLinus Torvalds {
841da177e4SLinus Torvalds 	struct bus_attribute * bus_attr = to_bus_attr(attr);
851da177e4SLinus Torvalds 	struct bus_type * bus = to_bus(kobj);
861da177e4SLinus Torvalds 	ssize_t ret = 0;
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds 	if (bus_attr->show)
891da177e4SLinus Torvalds 		ret = bus_attr->show(bus, buf);
901da177e4SLinus Torvalds 	return ret;
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds static ssize_t
941da177e4SLinus Torvalds bus_attr_store(struct kobject * kobj, struct attribute * attr,
951da177e4SLinus Torvalds 	       const char * buf, size_t count)
961da177e4SLinus Torvalds {
971da177e4SLinus Torvalds 	struct bus_attribute * bus_attr = to_bus_attr(attr);
981da177e4SLinus Torvalds 	struct bus_type * bus = to_bus(kobj);
991da177e4SLinus Torvalds 	ssize_t ret = 0;
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds 	if (bus_attr->store)
1021da177e4SLinus Torvalds 		ret = bus_attr->store(bus, buf, count);
1031da177e4SLinus Torvalds 	return ret;
1041da177e4SLinus Torvalds }
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds static struct sysfs_ops bus_sysfs_ops = {
1071da177e4SLinus Torvalds 	.show	= bus_attr_show,
1081da177e4SLinus Torvalds 	.store	= bus_attr_store,
1091da177e4SLinus Torvalds };
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	int error;
1141da177e4SLinus Torvalds 	if (get_bus(bus)) {
1151da177e4SLinus Torvalds 		error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr);
1161da177e4SLinus Torvalds 		put_bus(bus);
1171da177e4SLinus Torvalds 	} else
1181da177e4SLinus Torvalds 		error = -EINVAL;
1191da177e4SLinus Torvalds 	return error;
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
1231da177e4SLinus Torvalds {
1241da177e4SLinus Torvalds 	if (get_bus(bus)) {
1251da177e4SLinus Torvalds 		sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr);
1261da177e4SLinus Torvalds 		put_bus(bus);
1271da177e4SLinus Torvalds 	}
1281da177e4SLinus Torvalds }
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds static struct kobj_type ktype_bus = {
1311da177e4SLinus Torvalds 	.sysfs_ops	= &bus_sysfs_ops,
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds };
1341da177e4SLinus Torvalds 
1357e4ef085SAdrian Bunk static decl_subsys(bus, &ktype_bus, NULL);
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 
1382139bdd5SRussell King #ifdef CONFIG_HOTPLUG
1392b08c8d0SAlan Stern /* Manually detach a device from its associated driver. */
140151ef38fSGreg Kroah-Hartman static int driver_helper(struct device *dev, void *data)
141151ef38fSGreg Kroah-Hartman {
142151ef38fSGreg Kroah-Hartman 	const char *name = data;
143151ef38fSGreg Kroah-Hartman 
144151ef38fSGreg Kroah-Hartman 	if (strcmp(name, dev->bus_id) == 0)
145151ef38fSGreg Kroah-Hartman 		return 1;
146151ef38fSGreg Kroah-Hartman 	return 0;
147151ef38fSGreg Kroah-Hartman }
148151ef38fSGreg Kroah-Hartman 
149151ef38fSGreg Kroah-Hartman static ssize_t driver_unbind(struct device_driver *drv,
150151ef38fSGreg Kroah-Hartman 			     const char *buf, size_t count)
151151ef38fSGreg Kroah-Hartman {
152151ef38fSGreg Kroah-Hartman 	struct bus_type *bus = get_bus(drv->bus);
153151ef38fSGreg Kroah-Hartman 	struct device *dev;
154151ef38fSGreg Kroah-Hartman 	int err = -ENODEV;
155151ef38fSGreg Kroah-Hartman 
156151ef38fSGreg Kroah-Hartman 	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
1572b08c8d0SAlan Stern 	if (dev && dev->driver == drv) {
158bf74ad5bSAlan Stern 		if (dev->parent)	/* Needed for USB */
159bf74ad5bSAlan Stern 			down(&dev->parent->sem);
160151ef38fSGreg Kroah-Hartman 		device_release_driver(dev);
161bf74ad5bSAlan Stern 		if (dev->parent)
162bf74ad5bSAlan Stern 			up(&dev->parent->sem);
163151ef38fSGreg Kroah-Hartman 		err = count;
164151ef38fSGreg Kroah-Hartman 	}
1652b08c8d0SAlan Stern 	put_device(dev);
1662b08c8d0SAlan Stern 	put_bus(bus);
167151ef38fSGreg Kroah-Hartman 	return err;
168151ef38fSGreg Kroah-Hartman }
169151ef38fSGreg Kroah-Hartman static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
170151ef38fSGreg Kroah-Hartman 
171afdce75fSGreg Kroah-Hartman /*
172afdce75fSGreg Kroah-Hartman  * Manually attach a device to a driver.
173afdce75fSGreg Kroah-Hartman  * Note: the driver must want to bind to the device,
174afdce75fSGreg Kroah-Hartman  * it is not possible to override the driver's id table.
175afdce75fSGreg Kroah-Hartman  */
176afdce75fSGreg Kroah-Hartman static ssize_t driver_bind(struct device_driver *drv,
177afdce75fSGreg Kroah-Hartman 			   const char *buf, size_t count)
178afdce75fSGreg Kroah-Hartman {
179afdce75fSGreg Kroah-Hartman 	struct bus_type *bus = get_bus(drv->bus);
180afdce75fSGreg Kroah-Hartman 	struct device *dev;
181afdce75fSGreg Kroah-Hartman 	int err = -ENODEV;
182afdce75fSGreg Kroah-Hartman 
183afdce75fSGreg Kroah-Hartman 	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
1842b08c8d0SAlan Stern 	if (dev && dev->driver == NULL) {
185bf74ad5bSAlan Stern 		if (dev->parent)	/* Needed for USB */
186bf74ad5bSAlan Stern 			down(&dev->parent->sem);
187afdce75fSGreg Kroah-Hartman 		down(&dev->sem);
188afdce75fSGreg Kroah-Hartman 		err = driver_probe_device(drv, dev);
189afdce75fSGreg Kroah-Hartman 		up(&dev->sem);
190bf74ad5bSAlan Stern 		if (dev->parent)
191bf74ad5bSAlan Stern 			up(&dev->parent->sem);
19237225401SRyan Wilson 
19337225401SRyan Wilson 		if (err > 0) 		/* success */
19437225401SRyan Wilson 			err = count;
19537225401SRyan Wilson 		else if (err == 0)	/* driver didn't accept device */
19637225401SRyan Wilson 			err = -ENODEV;
197afdce75fSGreg Kroah-Hartman 	}
1982b08c8d0SAlan Stern 	put_device(dev);
1992b08c8d0SAlan Stern 	put_bus(bus);
200afdce75fSGreg Kroah-Hartman 	return err;
201afdce75fSGreg Kroah-Hartman }
202afdce75fSGreg Kroah-Hartman static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
203afdce75fSGreg Kroah-Hartman 
204*b8c5cec2SKay Sievers static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
205*b8c5cec2SKay Sievers {
206*b8c5cec2SKay Sievers 	return sprintf(buf, "%d\n", bus->drivers_autoprobe);
207*b8c5cec2SKay Sievers }
208*b8c5cec2SKay Sievers 
209*b8c5cec2SKay Sievers static ssize_t store_drivers_autoprobe(struct bus_type *bus,
210*b8c5cec2SKay Sievers 				       const char *buf, size_t count)
211*b8c5cec2SKay Sievers {
212*b8c5cec2SKay Sievers 	if (buf[0] == '0')
213*b8c5cec2SKay Sievers 		bus->drivers_autoprobe = 0;
214*b8c5cec2SKay Sievers 	else
215*b8c5cec2SKay Sievers 		bus->drivers_autoprobe = 1;
216*b8c5cec2SKay Sievers 	return count;
217*b8c5cec2SKay Sievers }
218*b8c5cec2SKay Sievers 
219*b8c5cec2SKay Sievers static ssize_t store_drivers_probe(struct bus_type *bus,
220*b8c5cec2SKay Sievers 				   const char *buf, size_t count)
221*b8c5cec2SKay Sievers {
222*b8c5cec2SKay Sievers 	struct device *dev;
223*b8c5cec2SKay Sievers 
224*b8c5cec2SKay Sievers 	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
225*b8c5cec2SKay Sievers 	if (!dev)
226*b8c5cec2SKay Sievers 		return -ENODEV;
227*b8c5cec2SKay Sievers 	if (bus_rescan_devices_helper(dev, NULL) != 0)
228*b8c5cec2SKay Sievers 		return -EINVAL;
229*b8c5cec2SKay Sievers 	return count;
230*b8c5cec2SKay Sievers }
2312139bdd5SRussell King #endif
232151ef38fSGreg Kroah-Hartman 
233465c7a3aSmochel@digitalimplant.org static struct device * next_device(struct klist_iter * i)
234465c7a3aSmochel@digitalimplant.org {
235465c7a3aSmochel@digitalimplant.org 	struct klist_node * n = klist_next(i);
236465c7a3aSmochel@digitalimplant.org 	return n ? container_of(n, struct device, knode_bus) : NULL;
237465c7a3aSmochel@digitalimplant.org }
238465c7a3aSmochel@digitalimplant.org 
2391da177e4SLinus Torvalds /**
2401da177e4SLinus Torvalds  *	bus_for_each_dev - device iterator.
2411da177e4SLinus Torvalds  *	@bus:	bus type.
2421da177e4SLinus Torvalds  *	@start:	device to start iterating from.
2431da177e4SLinus Torvalds  *	@data:	data for the callback.
2441da177e4SLinus Torvalds  *	@fn:	function to be called for each device.
2451da177e4SLinus Torvalds  *
2461da177e4SLinus Torvalds  *	Iterate over @bus's list of devices, and call @fn for each,
2471da177e4SLinus Torvalds  *	passing it @data. If @start is not NULL, we use that device to
2481da177e4SLinus Torvalds  *	begin iterating from.
2491da177e4SLinus Torvalds  *
2501da177e4SLinus Torvalds  *	We check the return of @fn each time. If it returns anything
2511da177e4SLinus Torvalds  *	other than 0, we break out and return that value.
2521da177e4SLinus Torvalds  *
2531da177e4SLinus Torvalds  *	NOTE: The device that returns a non-zero value is not retained
2541da177e4SLinus Torvalds  *	in any way, nor is its refcount incremented. If the caller needs
2551da177e4SLinus Torvalds  *	to retain this data, it should do, and increment the reference
2561da177e4SLinus Torvalds  *	count in the supplied callback.
2571da177e4SLinus Torvalds  */
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds int bus_for_each_dev(struct bus_type * bus, struct device * start,
2601da177e4SLinus Torvalds 		     void * data, int (*fn)(struct device *, void *))
2611da177e4SLinus Torvalds {
262465c7a3aSmochel@digitalimplant.org 	struct klist_iter i;
263465c7a3aSmochel@digitalimplant.org 	struct device * dev;
264465c7a3aSmochel@digitalimplant.org 	int error = 0;
2651da177e4SLinus Torvalds 
266465c7a3aSmochel@digitalimplant.org 	if (!bus)
267465c7a3aSmochel@digitalimplant.org 		return -EINVAL;
268465c7a3aSmochel@digitalimplant.org 
269465c7a3aSmochel@digitalimplant.org 	klist_iter_init_node(&bus->klist_devices, &i,
270465c7a3aSmochel@digitalimplant.org 			     (start ? &start->knode_bus : NULL));
271465c7a3aSmochel@digitalimplant.org 	while ((dev = next_device(&i)) && !error)
272465c7a3aSmochel@digitalimplant.org 		error = fn(dev, data);
273465c7a3aSmochel@digitalimplant.org 	klist_iter_exit(&i);
274465c7a3aSmochel@digitalimplant.org 	return error;
2751da177e4SLinus Torvalds }
2761da177e4SLinus Torvalds 
2770edb5860SCornelia Huck /**
2780edb5860SCornelia Huck  * bus_find_device - device iterator for locating a particular device.
2790edb5860SCornelia Huck  * @bus: bus type
2800edb5860SCornelia Huck  * @start: Device to begin with
2810edb5860SCornelia Huck  * @data: Data to pass to match function
2820edb5860SCornelia Huck  * @match: Callback function to check device
2830edb5860SCornelia Huck  *
2840edb5860SCornelia Huck  * This is similar to the bus_for_each_dev() function above, but it
2850edb5860SCornelia Huck  * returns a reference to a device that is 'found' for later use, as
2860edb5860SCornelia Huck  * determined by the @match callback.
2870edb5860SCornelia Huck  *
2880edb5860SCornelia Huck  * The callback should return 0 if the device doesn't match and non-zero
2890edb5860SCornelia Huck  * if it does.  If the callback returns non-zero, this function will
2900edb5860SCornelia Huck  * return to the caller and not iterate over any more devices.
2910edb5860SCornelia Huck  */
2920edb5860SCornelia Huck struct device * bus_find_device(struct bus_type *bus,
2930edb5860SCornelia Huck 				struct device *start, void *data,
2940edb5860SCornelia Huck 				int (*match)(struct device *, void *))
2950edb5860SCornelia Huck {
2960edb5860SCornelia Huck 	struct klist_iter i;
2970edb5860SCornelia Huck 	struct device *dev;
2980edb5860SCornelia Huck 
2990edb5860SCornelia Huck 	if (!bus)
3000edb5860SCornelia Huck 		return NULL;
3010edb5860SCornelia Huck 
3020edb5860SCornelia Huck 	klist_iter_init_node(&bus->klist_devices, &i,
3030edb5860SCornelia Huck 			     (start ? &start->knode_bus : NULL));
3040edb5860SCornelia Huck 	while ((dev = next_device(&i)))
3050edb5860SCornelia Huck 		if (match(dev, data) && get_device(dev))
3060edb5860SCornelia Huck 			break;
3070edb5860SCornelia Huck 	klist_iter_exit(&i);
3080edb5860SCornelia Huck 	return dev;
3090edb5860SCornelia Huck }
31038fdac3cSmochel@digitalimplant.org 
31138fdac3cSmochel@digitalimplant.org 
31238fdac3cSmochel@digitalimplant.org static struct device_driver * next_driver(struct klist_iter * i)
31338fdac3cSmochel@digitalimplant.org {
31438fdac3cSmochel@digitalimplant.org 	struct klist_node * n = klist_next(i);
31538fdac3cSmochel@digitalimplant.org 	return n ? container_of(n, struct device_driver, knode_bus) : NULL;
31638fdac3cSmochel@digitalimplant.org }
31738fdac3cSmochel@digitalimplant.org 
3181da177e4SLinus Torvalds /**
3191da177e4SLinus Torvalds  *	bus_for_each_drv - driver iterator
3201da177e4SLinus Torvalds  *	@bus:	bus we're dealing with.
3211da177e4SLinus Torvalds  *	@start:	driver to start iterating on.
3221da177e4SLinus Torvalds  *	@data:	data to pass to the callback.
3231da177e4SLinus Torvalds  *	@fn:	function to call for each driver.
3241da177e4SLinus Torvalds  *
3251da177e4SLinus Torvalds  *	This is nearly identical to the device iterator above.
3261da177e4SLinus Torvalds  *	We iterate over each driver that belongs to @bus, and call
3271da177e4SLinus Torvalds  *	@fn for each. If @fn returns anything but 0, we break out
3281da177e4SLinus Torvalds  *	and return it. If @start is not NULL, we use it as the head
3291da177e4SLinus Torvalds  *	of the list.
3301da177e4SLinus Torvalds  *
3311da177e4SLinus Torvalds  *	NOTE: we don't return the driver that returns a non-zero
3321da177e4SLinus Torvalds  *	value, nor do we leave the reference count incremented for that
3331da177e4SLinus Torvalds  *	driver. If the caller needs to know that info, it must set it
3341da177e4SLinus Torvalds  *	in the callback. It must also be sure to increment the refcount
3351da177e4SLinus Torvalds  *	so it doesn't disappear before returning to the caller.
3361da177e4SLinus Torvalds  */
3371da177e4SLinus Torvalds 
3381da177e4SLinus Torvalds int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
3391da177e4SLinus Torvalds 		     void * data, int (*fn)(struct device_driver *, void *))
3401da177e4SLinus Torvalds {
34138fdac3cSmochel@digitalimplant.org 	struct klist_iter i;
34238fdac3cSmochel@digitalimplant.org 	struct device_driver * drv;
34338fdac3cSmochel@digitalimplant.org 	int error = 0;
3441da177e4SLinus Torvalds 
34538fdac3cSmochel@digitalimplant.org 	if (!bus)
34638fdac3cSmochel@digitalimplant.org 		return -EINVAL;
34738fdac3cSmochel@digitalimplant.org 
34838fdac3cSmochel@digitalimplant.org 	klist_iter_init_node(&bus->klist_drivers, &i,
34938fdac3cSmochel@digitalimplant.org 			     start ? &start->knode_bus : NULL);
35038fdac3cSmochel@digitalimplant.org 	while ((drv = next_driver(&i)) && !error)
35138fdac3cSmochel@digitalimplant.org 		error = fn(drv, data);
35238fdac3cSmochel@digitalimplant.org 	klist_iter_exit(&i);
35338fdac3cSmochel@digitalimplant.org 	return error;
3541da177e4SLinus Torvalds }
3551da177e4SLinus Torvalds 
3561da177e4SLinus Torvalds static int device_add_attrs(struct bus_type *bus, struct device *dev)
3571da177e4SLinus Torvalds {
3581da177e4SLinus Torvalds 	int error = 0;
3591da177e4SLinus Torvalds 	int i;
3601da177e4SLinus Torvalds 
3614aca67e5SAndrew Morton 	if (!bus->dev_attrs)
3624aca67e5SAndrew Morton 		return 0;
3634aca67e5SAndrew Morton 
3641da177e4SLinus Torvalds 	for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
3651da177e4SLinus Torvalds 		error = device_create_file(dev,&bus->dev_attrs[i]);
3664aca67e5SAndrew Morton 		if (error) {
3671da177e4SLinus Torvalds 			while (--i >= 0)
3681da177e4SLinus Torvalds 				device_remove_file(dev, &bus->dev_attrs[i]);
3694aca67e5SAndrew Morton 			break;
3701da177e4SLinus Torvalds 		}
3714aca67e5SAndrew Morton 	}
3724aca67e5SAndrew Morton 	return error;
3734aca67e5SAndrew Morton }
3741da177e4SLinus Torvalds 
3751da177e4SLinus Torvalds static void device_remove_attrs(struct bus_type * bus, struct device * dev)
3761da177e4SLinus Torvalds {
3771da177e4SLinus Torvalds 	int i;
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds 	if (bus->dev_attrs) {
3801da177e4SLinus Torvalds 		for (i = 0; attr_name(bus->dev_attrs[i]); i++)
3811da177e4SLinus Torvalds 			device_remove_file(dev,&bus->dev_attrs[i]);
3821da177e4SLinus Torvalds 	}
3831da177e4SLinus Torvalds }
3841da177e4SLinus Torvalds 
385b9cafc7dSKay Sievers #ifdef CONFIG_SYSFS_DEPRECATED
386b9cafc7dSKay Sievers static int make_deprecated_bus_links(struct device *dev)
387b9cafc7dSKay Sievers {
388b9cafc7dSKay Sievers 	return sysfs_create_link(&dev->kobj,
389b9cafc7dSKay Sievers 				 &dev->bus->subsys.kset.kobj, "bus");
390b9cafc7dSKay Sievers }
391b9cafc7dSKay Sievers 
392b9cafc7dSKay Sievers static void remove_deprecated_bus_links(struct device *dev)
393b9cafc7dSKay Sievers {
394b9cafc7dSKay Sievers 	sysfs_remove_link(&dev->kobj, "bus");
395b9cafc7dSKay Sievers }
396b9cafc7dSKay Sievers #else
397b9cafc7dSKay Sievers static inline int make_deprecated_bus_links(struct device *dev) { return 0; }
398b9cafc7dSKay Sievers static inline void remove_deprecated_bus_links(struct device *dev) { }
399b9cafc7dSKay Sievers #endif
4001da177e4SLinus Torvalds 
4011da177e4SLinus Torvalds /**
4021da177e4SLinus Torvalds  *	bus_add_device - add device to bus
4031da177e4SLinus Torvalds  *	@dev:	device being added
4041da177e4SLinus Torvalds  *
4051da177e4SLinus Torvalds  *	- Add the device to its bus's list of devices.
40653877d06SKay Sievers  *	- Create link to device's bus.
4071da177e4SLinus Torvalds  */
4081da177e4SLinus Torvalds int bus_add_device(struct device * dev)
4091da177e4SLinus Torvalds {
4101da177e4SLinus Torvalds 	struct bus_type * bus = get_bus(dev->bus);
4111da177e4SLinus Torvalds 	int error = 0;
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 	if (bus) {
4141da177e4SLinus Torvalds 		pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
415ca2b94baSHannes Reinecke 		error = device_add_attrs(bus, dev);
416f86db396SAndrew Morton 		if (error)
417513e7337SCornelia Huck 			goto out_put;
418f86db396SAndrew Morton 		error = sysfs_create_link(&bus->devices.kobj,
419f86db396SAndrew Morton 						&dev->kobj, dev->bus_id);
420f86db396SAndrew Morton 		if (error)
421513e7337SCornelia Huck 			goto out_id;
422f86db396SAndrew Morton 		error = sysfs_create_link(&dev->kobj,
423f86db396SAndrew Morton 				&dev->bus->subsys.kset.kobj, "subsystem");
424f86db396SAndrew Morton 		if (error)
425513e7337SCornelia Huck 			goto out_subsys;
426b9cafc7dSKay Sievers 		error = make_deprecated_bus_links(dev);
427513e7337SCornelia Huck 		if (error)
428513e7337SCornelia Huck 			goto out_deprecated;
4291da177e4SLinus Torvalds 	}
430513e7337SCornelia Huck 	return 0;
431513e7337SCornelia Huck 
432513e7337SCornelia Huck out_deprecated:
433513e7337SCornelia Huck 	sysfs_remove_link(&dev->kobj, "subsystem");
434513e7337SCornelia Huck out_subsys:
435513e7337SCornelia Huck 	sysfs_remove_link(&bus->devices.kobj, dev->bus_id);
436513e7337SCornelia Huck out_id:
437513e7337SCornelia Huck 	device_remove_attrs(bus, dev);
438513e7337SCornelia Huck out_put:
439513e7337SCornelia Huck 	put_bus(dev->bus);
4401da177e4SLinus Torvalds 	return error;
4411da177e4SLinus Torvalds }
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds /**
44453877d06SKay Sievers  *	bus_attach_device - add device to bus
44553877d06SKay Sievers  *	@dev:	device tried to attach to a driver
44653877d06SKay Sievers  *
447f2eaae19SAlan Stern  *	- Add device to bus's list of devices.
44853877d06SKay Sievers  *	- Try to attach to driver.
44953877d06SKay Sievers  */
450f86db396SAndrew Morton int bus_attach_device(struct device * dev)
45153877d06SKay Sievers {
45253877d06SKay Sievers 	struct bus_type *bus = dev->bus;
453f86db396SAndrew Morton 	int ret = 0;
45453877d06SKay Sievers 
45553877d06SKay Sievers 	if (bus) {
456f2eaae19SAlan Stern 		dev->is_registered = 1;
457*b8c5cec2SKay Sievers 		if (bus->drivers_autoprobe)
458f86db396SAndrew Morton 			ret = device_attach(dev);
459f86db396SAndrew Morton 		if (ret >= 0) {
46053877d06SKay Sievers 			klist_add_tail(&dev->knode_bus, &bus->klist_devices);
461f86db396SAndrew Morton 			ret = 0;
462f2eaae19SAlan Stern 		} else
463f2eaae19SAlan Stern 			dev->is_registered = 0;
46453877d06SKay Sievers 	}
465f86db396SAndrew Morton 	return ret;
466f86db396SAndrew Morton }
46753877d06SKay Sievers 
46853877d06SKay Sievers /**
4691da177e4SLinus Torvalds  *	bus_remove_device - remove device from bus
4701da177e4SLinus Torvalds  *	@dev:	device to be removed
4711da177e4SLinus Torvalds  *
4721da177e4SLinus Torvalds  *	- Remove symlink from bus's directory.
4731da177e4SLinus Torvalds  *	- Delete device from bus's list.
4741da177e4SLinus Torvalds  *	- Detach from its driver.
4751da177e4SLinus Torvalds  *	- Drop reference taken in bus_add_device().
4761da177e4SLinus Torvalds  */
4771da177e4SLinus Torvalds void bus_remove_device(struct device * dev)
4781da177e4SLinus Torvalds {
4791da177e4SLinus Torvalds 	if (dev->bus) {
480b9d9c82bSKay Sievers 		sysfs_remove_link(&dev->kobj, "subsystem");
481b9cafc7dSKay Sievers 		remove_deprecated_bus_links(dev);
4821da177e4SLinus Torvalds 		sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
4831da177e4SLinus Torvalds 		device_remove_attrs(dev->bus, dev);
484f70fa629SAlan Stern 		if (dev->is_registered) {
485f2eaae19SAlan Stern 			dev->is_registered = 0;
486f2eaae19SAlan Stern 			klist_del(&dev->knode_bus);
487f70fa629SAlan Stern 		}
4881da177e4SLinus Torvalds 		pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
4891da177e4SLinus Torvalds 		device_release_driver(dev);
4901da177e4SLinus Torvalds 		put_bus(dev->bus);
4911da177e4SLinus Torvalds 	}
4921da177e4SLinus Torvalds }
4931da177e4SLinus Torvalds 
4941da177e4SLinus Torvalds static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv)
4951da177e4SLinus Torvalds {
4961da177e4SLinus Torvalds 	int error = 0;
4971da177e4SLinus Torvalds 	int i;
4981da177e4SLinus Torvalds 
4991da177e4SLinus Torvalds 	if (bus->drv_attrs) {
5001da177e4SLinus Torvalds 		for (i = 0; attr_name(bus->drv_attrs[i]); i++) {
5011da177e4SLinus Torvalds 			error = driver_create_file(drv, &bus->drv_attrs[i]);
5021da177e4SLinus Torvalds 			if (error)
5031da177e4SLinus Torvalds 				goto Err;
5041da177e4SLinus Torvalds 		}
5051da177e4SLinus Torvalds 	}
5061da177e4SLinus Torvalds  Done:
5071da177e4SLinus Torvalds 	return error;
5081da177e4SLinus Torvalds  Err:
5091da177e4SLinus Torvalds 	while (--i >= 0)
5101da177e4SLinus Torvalds 		driver_remove_file(drv, &bus->drv_attrs[i]);
5111da177e4SLinus Torvalds 	goto Done;
5121da177e4SLinus Torvalds }
5131da177e4SLinus Torvalds 
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv)
5161da177e4SLinus Torvalds {
5171da177e4SLinus Torvalds 	int i;
5181da177e4SLinus Torvalds 
5191da177e4SLinus Torvalds 	if (bus->drv_attrs) {
5201da177e4SLinus Torvalds 		for (i = 0; attr_name(bus->drv_attrs[i]); i++)
5211da177e4SLinus Torvalds 			driver_remove_file(drv, &bus->drv_attrs[i]);
5221da177e4SLinus Torvalds 	}
5231da177e4SLinus Torvalds }
5241da177e4SLinus Torvalds 
525874c6241SGreg Kroah-Hartman #ifdef CONFIG_HOTPLUG
526874c6241SGreg Kroah-Hartman /*
527874c6241SGreg Kroah-Hartman  * Thanks to drivers making their tables __devinit, we can't allow manual
528874c6241SGreg Kroah-Hartman  * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
529874c6241SGreg Kroah-Hartman  */
530f86db396SAndrew Morton static int __must_check add_bind_files(struct device_driver *drv)
531874c6241SGreg Kroah-Hartman {
532f86db396SAndrew Morton 	int ret;
533f86db396SAndrew Morton 
534f86db396SAndrew Morton 	ret = driver_create_file(drv, &driver_attr_unbind);
535f86db396SAndrew Morton 	if (ret == 0) {
536f86db396SAndrew Morton 		ret = driver_create_file(drv, &driver_attr_bind);
537f86db396SAndrew Morton 		if (ret)
538f86db396SAndrew Morton 			driver_remove_file(drv, &driver_attr_unbind);
539f86db396SAndrew Morton 	}
540f86db396SAndrew Morton 	return ret;
541874c6241SGreg Kroah-Hartman }
542874c6241SGreg Kroah-Hartman 
543874c6241SGreg Kroah-Hartman static void remove_bind_files(struct device_driver *drv)
544874c6241SGreg Kroah-Hartman {
545874c6241SGreg Kroah-Hartman 	driver_remove_file(drv, &driver_attr_bind);
546874c6241SGreg Kroah-Hartman 	driver_remove_file(drv, &driver_attr_unbind);
547874c6241SGreg Kroah-Hartman }
548*b8c5cec2SKay Sievers 
549*b8c5cec2SKay Sievers static int add_probe_files(struct bus_type *bus)
550*b8c5cec2SKay Sievers {
551*b8c5cec2SKay Sievers 	int retval;
552*b8c5cec2SKay Sievers 
553*b8c5cec2SKay Sievers 	bus->drivers_probe_attr.attr.name = "drivers_probe";
554*b8c5cec2SKay Sievers 	bus->drivers_probe_attr.attr.mode = S_IWUSR;
555*b8c5cec2SKay Sievers 	bus->drivers_probe_attr.attr.owner = bus->owner;
556*b8c5cec2SKay Sievers 	bus->drivers_probe_attr.store = store_drivers_probe;
557*b8c5cec2SKay Sievers 	retval = bus_create_file(bus, &bus->drivers_probe_attr);
558*b8c5cec2SKay Sievers 	if (retval)
559*b8c5cec2SKay Sievers 		goto out;
560*b8c5cec2SKay Sievers 
561*b8c5cec2SKay Sievers 	bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe";
562*b8c5cec2SKay Sievers 	bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
563*b8c5cec2SKay Sievers 	bus->drivers_autoprobe_attr.attr.owner = bus->owner;
564*b8c5cec2SKay Sievers 	bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
565*b8c5cec2SKay Sievers 	bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
566*b8c5cec2SKay Sievers 	retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
567*b8c5cec2SKay Sievers 	if (retval)
568*b8c5cec2SKay Sievers 		bus_remove_file(bus, &bus->drivers_probe_attr);
569*b8c5cec2SKay Sievers out:
570*b8c5cec2SKay Sievers 	return retval;
571*b8c5cec2SKay Sievers }
572*b8c5cec2SKay Sievers 
573*b8c5cec2SKay Sievers static void remove_probe_files(struct bus_type *bus)
574*b8c5cec2SKay Sievers {
575*b8c5cec2SKay Sievers 	bus_remove_file(bus, &bus->drivers_autoprobe_attr);
576*b8c5cec2SKay Sievers 	bus_remove_file(bus, &bus->drivers_probe_attr);
577*b8c5cec2SKay Sievers }
578874c6241SGreg Kroah-Hartman #else
57935acfdd7SYoichi Yuasa static inline int add_bind_files(struct device_driver *drv) { return 0; }
580874c6241SGreg Kroah-Hartman static inline void remove_bind_files(struct device_driver *drv) {}
581*b8c5cec2SKay Sievers static inline int add_probe_files(struct bus_type *bus) { return 0; }
582*b8c5cec2SKay Sievers static inline void remove_probe_files(struct bus_type *bus) {}
583874c6241SGreg Kroah-Hartman #endif
5841da177e4SLinus Torvalds 
5851da177e4SLinus Torvalds /**
5861da177e4SLinus Torvalds  *	bus_add_driver - Add a driver to the bus.
5871da177e4SLinus Torvalds  *	@drv:	driver.
5881da177e4SLinus Torvalds  *
5891da177e4SLinus Torvalds  */
5901da177e4SLinus Torvalds int bus_add_driver(struct device_driver *drv)
5911da177e4SLinus Torvalds {
5921da177e4SLinus Torvalds 	struct bus_type * bus = get_bus(drv->bus);
5931da177e4SLinus Torvalds 	int error = 0;
5941da177e4SLinus Torvalds 
595d9fd4d3bSJeff Garzik 	if (!bus)
596d9fd4d3bSJeff Garzik 		return 0;
597d9fd4d3bSJeff Garzik 
5981da177e4SLinus Torvalds 	pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
5991da177e4SLinus Torvalds 	error = kobject_set_name(&drv->kobj, "%s", drv->name);
600f86db396SAndrew Morton 	if (error)
601f86db396SAndrew Morton 		goto out_put_bus;
6021da177e4SLinus Torvalds 	drv->kobj.kset = &bus->drivers;
603f86db396SAndrew Morton 	if ((error = kobject_register(&drv->kobj)))
604f86db396SAndrew Morton 		goto out_put_bus;
6051da177e4SLinus Torvalds 
606*b8c5cec2SKay Sievers 	if (drv->bus->drivers_autoprobe) {
607f86db396SAndrew Morton 		error = driver_attach(drv);
608f86db396SAndrew Morton 		if (error)
609f86db396SAndrew Morton 			goto out_unregister;
610*b8c5cec2SKay Sievers 	}
611d856f1e3SJames Bottomley 	klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
6121da177e4SLinus Torvalds 	module_add_driver(drv->owner, drv);
6131da177e4SLinus Torvalds 
614f86db396SAndrew Morton 	error = driver_add_attrs(bus, drv);
615f86db396SAndrew Morton 	if (error) {
616f86db396SAndrew Morton 		/* How the hell do we get out of this pickle? Give up */
617f86db396SAndrew Morton 		printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
618f86db396SAndrew Morton 			__FUNCTION__, drv->name);
619f86db396SAndrew Morton 	}
620f86db396SAndrew Morton 	error = add_bind_files(drv);
621f86db396SAndrew Morton 	if (error) {
622f86db396SAndrew Morton 		/* Ditto */
623f86db396SAndrew Morton 		printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
624f86db396SAndrew Morton 			__FUNCTION__, drv->name);
625f86db396SAndrew Morton 	}
626d9fd4d3bSJeff Garzik 
6271da177e4SLinus Torvalds 	return error;
628f86db396SAndrew Morton out_unregister:
629f86db396SAndrew Morton 	kobject_unregister(&drv->kobj);
630f86db396SAndrew Morton out_put_bus:
631f86db396SAndrew Morton 	put_bus(bus);
632f86db396SAndrew Morton 	return error;
6331da177e4SLinus Torvalds }
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds /**
6361da177e4SLinus Torvalds  *	bus_remove_driver - delete driver from bus's knowledge.
6371da177e4SLinus Torvalds  *	@drv:	driver.
6381da177e4SLinus Torvalds  *
6391da177e4SLinus Torvalds  *	Detach the driver from the devices it controls, and remove
6401da177e4SLinus Torvalds  *	it from its bus's list of drivers. Finally, we drop the reference
6411da177e4SLinus Torvalds  *	to the bus we took in bus_add_driver().
6421da177e4SLinus Torvalds  */
6431da177e4SLinus Torvalds 
6441da177e4SLinus Torvalds void bus_remove_driver(struct device_driver * drv)
6451da177e4SLinus Torvalds {
646d9fd4d3bSJeff Garzik 	if (!drv->bus)
647d9fd4d3bSJeff Garzik 		return;
648d9fd4d3bSJeff Garzik 
649874c6241SGreg Kroah-Hartman 	remove_bind_files(drv);
6501da177e4SLinus Torvalds 	driver_remove_attrs(drv->bus, drv);
65138fdac3cSmochel@digitalimplant.org 	klist_remove(&drv->knode_bus);
6521da177e4SLinus Torvalds 	pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
6531da177e4SLinus Torvalds 	driver_detach(drv);
6541da177e4SLinus Torvalds 	module_remove_driver(drv);
6551da177e4SLinus Torvalds 	kobject_unregister(&drv->kobj);
6561da177e4SLinus Torvalds 	put_bus(drv->bus);
6571da177e4SLinus Torvalds }
6581da177e4SLinus Torvalds 
6591da177e4SLinus Torvalds 
6601da177e4SLinus Torvalds /* Helper for bus_rescan_devices's iter */
661f86db396SAndrew Morton static int __must_check bus_rescan_devices_helper(struct device *dev,
662f86db396SAndrew Morton 						void *data)
6631da177e4SLinus Torvalds {
664f86db396SAndrew Morton 	int ret = 0;
665f86db396SAndrew Morton 
666bf74ad5bSAlan Stern 	if (!dev->driver) {
667bf74ad5bSAlan Stern 		if (dev->parent)	/* Needed for USB */
668bf74ad5bSAlan Stern 			down(&dev->parent->sem);
669f86db396SAndrew Morton 		ret = device_attach(dev);
670bf74ad5bSAlan Stern 		if (dev->parent)
671bf74ad5bSAlan Stern 			up(&dev->parent->sem);
672f86db396SAndrew Morton 		if (ret > 0)
673f86db396SAndrew Morton 			ret = 0;
674bf74ad5bSAlan Stern 	}
675f86db396SAndrew Morton 	return ret < 0 ? ret : 0;
6761da177e4SLinus Torvalds }
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds /**
6791da177e4SLinus Torvalds  * bus_rescan_devices - rescan devices on the bus for possible drivers
6801da177e4SLinus Torvalds  * @bus: the bus to scan.
6811da177e4SLinus Torvalds  *
6821da177e4SLinus Torvalds  * This function will look for devices on the bus with no driver
68323d3d602SGreg Kroah-Hartman  * attached and rescan it against existing drivers to see if it matches
68423d3d602SGreg Kroah-Hartman  * any by calling device_attach() for the unbound devices.
6851da177e4SLinus Torvalds  */
686f86db396SAndrew Morton int bus_rescan_devices(struct bus_type * bus)
6871da177e4SLinus Torvalds {
688f86db396SAndrew Morton 	return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
6891da177e4SLinus Torvalds }
6901da177e4SLinus Torvalds 
691e935d5daSMoore, Eric /**
692e935d5daSMoore, Eric  * device_reprobe - remove driver for a device and probe for a new driver
693e935d5daSMoore, Eric  * @dev: the device to reprobe
694e935d5daSMoore, Eric  *
695e935d5daSMoore, Eric  * This function detaches the attached driver (if any) for the given
696e935d5daSMoore, Eric  * device and restarts the driver probing process.  It is intended
697e935d5daSMoore, Eric  * to use if probing criteria changed during a devices lifetime and
698e935d5daSMoore, Eric  * driver attachment should change accordingly.
699e935d5daSMoore, Eric  */
700f86db396SAndrew Morton int device_reprobe(struct device *dev)
701e935d5daSMoore, Eric {
702e935d5daSMoore, Eric 	if (dev->driver) {
703e935d5daSMoore, Eric 		if (dev->parent)        /* Needed for USB */
704e935d5daSMoore, Eric 			down(&dev->parent->sem);
705e935d5daSMoore, Eric 		device_release_driver(dev);
706e935d5daSMoore, Eric 		if (dev->parent)
707e935d5daSMoore, Eric 			up(&dev->parent->sem);
708e935d5daSMoore, Eric 	}
709f86db396SAndrew Morton 	return bus_rescan_devices_helper(dev, NULL);
710e935d5daSMoore, Eric }
711e935d5daSMoore, Eric EXPORT_SYMBOL_GPL(device_reprobe);
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds struct bus_type *get_bus(struct bus_type *bus)
7141da177e4SLinus Torvalds {
715f86db396SAndrew Morton 	return bus ? container_of(subsys_get(&bus->subsys),
716f86db396SAndrew Morton 				struct bus_type, subsys) : NULL;
7171da177e4SLinus Torvalds }
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds void put_bus(struct bus_type * bus)
7201da177e4SLinus Torvalds {
7211da177e4SLinus Torvalds 	subsys_put(&bus->subsys);
7221da177e4SLinus Torvalds }
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds /**
7261da177e4SLinus Torvalds  *	find_bus - locate bus by name.
7271da177e4SLinus Torvalds  *	@name:	name of bus.
7281da177e4SLinus Torvalds  *
7291da177e4SLinus Torvalds  *	Call kset_find_obj() to iterate over list of buses to
7301da177e4SLinus Torvalds  *	find a bus by name. Return bus if found.
7311da177e4SLinus Torvalds  *
7321da177e4SLinus Torvalds  *	Note that kset_find_obj increments bus' reference count.
7331da177e4SLinus Torvalds  */
7347e4ef085SAdrian Bunk #if 0
7351da177e4SLinus Torvalds struct bus_type * find_bus(char * name)
7361da177e4SLinus Torvalds {
7371da177e4SLinus Torvalds 	struct kobject * k = kset_find_obj(&bus_subsys.kset, name);
7381da177e4SLinus Torvalds 	return k ? to_bus(k) : NULL;
7391da177e4SLinus Torvalds }
7407e4ef085SAdrian Bunk #endif  /*  0  */
7411da177e4SLinus Torvalds 
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds /**
7441da177e4SLinus Torvalds  *	bus_add_attrs - Add default attributes for this bus.
7451da177e4SLinus Torvalds  *	@bus:	Bus that has just been registered.
7461da177e4SLinus Torvalds  */
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds static int bus_add_attrs(struct bus_type * bus)
7491da177e4SLinus Torvalds {
7501da177e4SLinus Torvalds 	int error = 0;
7511da177e4SLinus Torvalds 	int i;
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds 	if (bus->bus_attrs) {
7541da177e4SLinus Torvalds 		for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
7551da177e4SLinus Torvalds 			if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
7561da177e4SLinus Torvalds 				goto Err;
7571da177e4SLinus Torvalds 		}
7581da177e4SLinus Torvalds 	}
7591da177e4SLinus Torvalds  Done:
7601da177e4SLinus Torvalds 	return error;
7611da177e4SLinus Torvalds  Err:
7621da177e4SLinus Torvalds 	while (--i >= 0)
7631da177e4SLinus Torvalds 		bus_remove_file(bus,&bus->bus_attrs[i]);
7641da177e4SLinus Torvalds 	goto Done;
7651da177e4SLinus Torvalds }
7661da177e4SLinus Torvalds 
7671da177e4SLinus Torvalds static void bus_remove_attrs(struct bus_type * bus)
7681da177e4SLinus Torvalds {
7691da177e4SLinus Torvalds 	int i;
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	if (bus->bus_attrs) {
7721da177e4SLinus Torvalds 		for (i = 0; attr_name(bus->bus_attrs[i]); i++)
7731da177e4SLinus Torvalds 			bus_remove_file(bus,&bus->bus_attrs[i]);
7741da177e4SLinus Torvalds 	}
7751da177e4SLinus Torvalds }
7761da177e4SLinus Torvalds 
77734bb61f9SJames Bottomley static void klist_devices_get(struct klist_node *n)
77834bb61f9SJames Bottomley {
77934bb61f9SJames Bottomley 	struct device *dev = container_of(n, struct device, knode_bus);
78034bb61f9SJames Bottomley 
78134bb61f9SJames Bottomley 	get_device(dev);
78234bb61f9SJames Bottomley }
78334bb61f9SJames Bottomley 
78434bb61f9SJames Bottomley static void klist_devices_put(struct klist_node *n)
78534bb61f9SJames Bottomley {
78634bb61f9SJames Bottomley 	struct device *dev = container_of(n, struct device, knode_bus);
78734bb61f9SJames Bottomley 
78834bb61f9SJames Bottomley 	put_device(dev);
78934bb61f9SJames Bottomley }
79034bb61f9SJames Bottomley 
7911da177e4SLinus Torvalds /**
7921da177e4SLinus Torvalds  *	bus_register - register a bus with the system.
7931da177e4SLinus Torvalds  *	@bus:	bus.
7941da177e4SLinus Torvalds  *
7951da177e4SLinus Torvalds  *	Once we have that, we registered the bus with the kobject
7961da177e4SLinus Torvalds  *	infrastructure, then register the children subsystems it has:
7971da177e4SLinus Torvalds  *	the devices and drivers that belong to the bus.
7981da177e4SLinus Torvalds  */
7991da177e4SLinus Torvalds int bus_register(struct bus_type * bus)
8001da177e4SLinus Torvalds {
8011da177e4SLinus Torvalds 	int retval;
8021da177e4SLinus Torvalds 
803116af378SBenjamin Herrenschmidt 	BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
804116af378SBenjamin Herrenschmidt 
8051da177e4SLinus Torvalds 	retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
8061da177e4SLinus Torvalds 	if (retval)
8071da177e4SLinus Torvalds 		goto out;
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	subsys_set_kset(bus, bus_subsys);
8101da177e4SLinus Torvalds 	retval = subsystem_register(&bus->subsys);
8111da177e4SLinus Torvalds 	if (retval)
8121da177e4SLinus Torvalds 		goto out;
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds 	kobject_set_name(&bus->devices.kobj, "devices");
8151da177e4SLinus Torvalds 	bus->devices.subsys = &bus->subsys;
8161da177e4SLinus Torvalds 	retval = kset_register(&bus->devices);
8171da177e4SLinus Torvalds 	if (retval)
8181da177e4SLinus Torvalds 		goto bus_devices_fail;
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds 	kobject_set_name(&bus->drivers.kobj, "drivers");
8211da177e4SLinus Torvalds 	bus->drivers.subsys = &bus->subsys;
8221da177e4SLinus Torvalds 	bus->drivers.ktype = &ktype_driver;
8231da177e4SLinus Torvalds 	retval = kset_register(&bus->drivers);
8241da177e4SLinus Torvalds 	if (retval)
8251da177e4SLinus Torvalds 		goto bus_drivers_fail;
826465c7a3aSmochel@digitalimplant.org 
82734bb61f9SJames Bottomley 	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
82881107bf5SAlan Stern 	klist_init(&bus->klist_drivers, NULL, NULL);
829*b8c5cec2SKay Sievers 
830*b8c5cec2SKay Sievers 	bus->drivers_autoprobe = 1;
831*b8c5cec2SKay Sievers 	retval = add_probe_files(bus);
832*b8c5cec2SKay Sievers 	if (retval)
833*b8c5cec2SKay Sievers 		goto bus_probe_files_fail;
834*b8c5cec2SKay Sievers 
8351bb6881aSCornelia Huck 	retval = bus_add_attrs(bus);
8361bb6881aSCornelia Huck 	if (retval)
8371bb6881aSCornelia Huck 		goto bus_attrs_fail;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	pr_debug("bus type '%s' registered\n", bus->name);
8401da177e4SLinus Torvalds 	return 0;
8411da177e4SLinus Torvalds 
8421bb6881aSCornelia Huck bus_attrs_fail:
843*b8c5cec2SKay Sievers 	remove_probe_files(bus);
844*b8c5cec2SKay Sievers bus_probe_files_fail:
8451bb6881aSCornelia Huck 	kset_unregister(&bus->drivers);
8461da177e4SLinus Torvalds bus_drivers_fail:
8471da177e4SLinus Torvalds 	kset_unregister(&bus->devices);
8481da177e4SLinus Torvalds bus_devices_fail:
8491da177e4SLinus Torvalds 	subsystem_unregister(&bus->subsys);
8501da177e4SLinus Torvalds out:
8511da177e4SLinus Torvalds 	return retval;
8521da177e4SLinus Torvalds }
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds /**
8551da177e4SLinus Torvalds  *	bus_unregister - remove a bus from the system
8561da177e4SLinus Torvalds  *	@bus:	bus.
8571da177e4SLinus Torvalds  *
8581da177e4SLinus Torvalds  *	Unregister the child subsystems and the bus itself.
8591da177e4SLinus Torvalds  *	Finally, we call put_bus() to release the refcount
8601da177e4SLinus Torvalds  */
8611da177e4SLinus Torvalds void bus_unregister(struct bus_type * bus)
8621da177e4SLinus Torvalds {
8631da177e4SLinus Torvalds 	pr_debug("bus %s: unregistering\n", bus->name);
8641da177e4SLinus Torvalds 	bus_remove_attrs(bus);
865*b8c5cec2SKay Sievers 	remove_probe_files(bus);
8661da177e4SLinus Torvalds 	kset_unregister(&bus->drivers);
8671da177e4SLinus Torvalds 	kset_unregister(&bus->devices);
8681da177e4SLinus Torvalds 	subsystem_unregister(&bus->subsys);
8691da177e4SLinus Torvalds }
8701da177e4SLinus Torvalds 
871116af378SBenjamin Herrenschmidt int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
872116af378SBenjamin Herrenschmidt {
873116af378SBenjamin Herrenschmidt 	return blocking_notifier_chain_register(&bus->bus_notifier, nb);
874116af378SBenjamin Herrenschmidt }
875116af378SBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(bus_register_notifier);
876116af378SBenjamin Herrenschmidt 
877116af378SBenjamin Herrenschmidt int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
878116af378SBenjamin Herrenschmidt {
879116af378SBenjamin Herrenschmidt 	return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
880116af378SBenjamin Herrenschmidt }
881116af378SBenjamin Herrenschmidt EXPORT_SYMBOL_GPL(bus_unregister_notifier);
882116af378SBenjamin Herrenschmidt 
8831da177e4SLinus Torvalds int __init buses_init(void)
8841da177e4SLinus Torvalds {
8851da177e4SLinus Torvalds 	return subsystem_register(&bus_subsys);
8861da177e4SLinus Torvalds }
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_for_each_dev);
8900edb5860SCornelia Huck EXPORT_SYMBOL_GPL(bus_find_device);
8911da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_for_each_drv);
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_register);
8941da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_unregister);
8951da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_rescan_devices);
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_create_file);
8981da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(bus_remove_file);
899