Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / drivers / base / bus.c
blob845c0a669f3254734b7196d25f7a8e4446898648
1 /*
2 * bus.c - bus driver management
3 *
4 * Copyright (c) 2002 Patrick Mochel
5 * 2002 Open Source Development Lab
6 *
7 *
8 */
10 #define DEBUG 0
12 #include <linux/device.h>
13 #include <linux/module.h>
14 #include <linux/errno.h>
15 #include <linux/init.h>
16 #include <linux/string.h>
17 #include "base.h"
19 static LIST_HEAD(bus_driver_list);
21 #define to_dev(node) container_of(node,struct device,bus_list)
22 #define to_drv(node) container_of(node,struct device_driver,bus_list)
24 #define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
25 #define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj)
28 * sysfs bindings for drivers
31 #define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
32 #define to_driver(obj) container_of(obj, struct device_driver, kobj)
35 static ssize_t
36 drv_attr_show(struct kobject * kobj, struct attribute * attr,
37 char * buf, size_t count, loff_t off)
39 struct driver_attribute * drv_attr = to_drv_attr(attr);
40 struct device_driver * drv = to_driver(kobj);
41 ssize_t ret = 0;
43 if (drv_attr->show)
44 ret = drv_attr->show(drv,buf,count,off);
45 return ret;
48 static ssize_t
49 drv_attr_store(struct kobject * kobj, struct attribute * attr,
50 const char * buf, size_t count, loff_t off)
52 struct driver_attribute * drv_attr = to_drv_attr(attr);
53 struct device_driver * drv = to_driver(kobj);
54 ssize_t ret = 0;
56 if (drv_attr->store)
57 ret = drv_attr->store(drv,buf,count,off);
58 return ret;
61 static struct sysfs_ops driver_sysfs_ops = {
62 .show = drv_attr_show,
63 .store = drv_attr_store,
68 * sysfs bindings for drivers
72 static ssize_t
73 bus_attr_show(struct kobject * kobj, struct attribute * attr,
74 char * buf, size_t count, loff_t off)
76 struct bus_attribute * bus_attr = to_bus_attr(attr);
77 struct bus_type * bus = to_bus(kobj);
78 ssize_t ret = 0;
80 if (bus_attr->show)
81 ret = bus_attr->show(bus,buf,count,off);
82 return ret;
85 static ssize_t
86 bus_attr_store(struct kobject * kobj, struct attribute * attr,
87 const char * buf, size_t count, loff_t off)
89 struct bus_attribute * bus_attr = to_bus_attr(attr);
90 struct bus_type * bus = to_bus(kobj);
91 ssize_t ret = 0;
93 if (bus_attr->store)
94 ret = bus_attr->store(bus,buf,count,off);
95 return ret;
98 static struct sysfs_ops bus_sysfs_ops = {
99 .show = bus_attr_show,
100 .store = bus_attr_store,
103 int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
105 int error;
106 if (get_bus(bus)) {
107 error = sysfs_create_file(&bus->subsys.kobj,&attr->attr);
108 put_bus(bus);
109 } else
110 error = -EINVAL;
111 return error;
114 void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
116 if (get_bus(bus)) {
117 sysfs_remove_file(&bus->subsys.kobj,&attr->attr);
118 put_bus(bus);
122 struct subsystem bus_subsys = {
123 .kobj = { .name = "bus" },
124 .sysfs_ops = &bus_sysfs_ops,
128 * bus_for_each_dev - walk list of devices and do something to each
129 * @bus: bus in question
130 * @data: data for the callback
131 * @callback: caller-defined action to perform on each device
133 * Why do we do this? So we can guarantee proper locking and reference
134 * counting on devices as we touch each one.
136 * Algorithm:
137 * Take device_lock and get the first node in the list.
138 * Try and increment the reference count on it. If we can't, it's in the
139 * process of being removed, but that process hasn't acquired device_lock.
140 * It's still in the list, so we grab the next node and try that one.
141 * We drop the lock to call the callback.
142 * We can't decrement the reference count yet, because we need the next
143 * node in the list. So, we set @prev to point to the current device.
144 * On the next go-round, we decrement the reference count on @prev, so if
145 * it's being removed, it won't affect us.
147 int bus_for_each_dev(struct bus_type * bus, void * data,
148 int (*callback)(struct device * dev, void * data))
150 struct list_head * node;
151 int error = 0;
153 bus = get_bus(bus);
154 if (bus) {
155 down_read(&bus->rwsem);
156 list_for_each(node,&bus->devices) {
157 struct device * dev = get_device(to_dev(node));
158 if (dev) {
159 error = callback(dev,data);
160 put_device(dev);
161 if (error)
162 break;
165 up_read(&bus->rwsem);
166 put_bus(bus);
168 return error;
171 int bus_for_each_drv(struct bus_type * bus, void * data,
172 int (*callback)(struct device_driver * drv, void * data))
174 struct list_head * node;
175 int error = 0;
177 bus = get_bus(bus);
178 if (bus) {
179 down_read(&bus->rwsem);
180 list_for_each(node,&bus->drivers) {
181 struct device_driver * drv = get_driver(to_drv(node));
182 if (drv) {
183 error = callback(drv,data);
184 put_driver(drv);
185 if (error)
186 break;
189 up_read(&bus->rwsem);
190 put_bus(bus);
192 return error;
195 static void attach(struct device * dev)
197 pr_debug("bound device '%s' to driver '%s'\n",
198 dev->bus_id,dev->driver->name);
199 list_add_tail(&dev->driver_list,&dev->driver->devices);
200 sysfs_create_link(&dev->driver->kobj,&dev->kobj,dev->kobj.name);
203 static int bus_match(struct device * dev, struct device_driver * drv)
205 int error = -ENODEV;
206 if (dev->bus->match(dev,drv)) {
207 dev->driver = drv;
208 if (drv->probe) {
209 if (!(error = drv->probe(dev)))
210 attach(dev);
211 else
212 dev->driver = NULL;
213 } else
214 attach(dev);
216 return error;
219 static int device_attach(struct device * dev)
221 struct bus_type * bus = dev->bus;
222 struct list_head * entry;
223 int error = 0;
225 if (dev->driver) {
226 attach(dev);
227 return 0;
230 if (!bus->match)
231 return 0;
233 list_for_each(entry,&bus->drivers) {
234 struct device_driver * drv =
235 get_driver(container_of(entry,struct device_driver,bus_list));
236 if (!drv)
237 continue;
238 error = bus_match(dev,drv);
239 put_driver(drv);
240 if (!error)
241 break;
243 return error;
246 static int driver_attach(struct device_driver * drv)
248 struct bus_type * bus = drv->bus;
249 struct list_head * entry;
250 int error = 0;
252 if (!bus->match)
253 return 0;
255 list_for_each(entry,&bus->devices) {
256 struct device * dev = container_of(entry,struct device,bus_list);
257 if (get_device(dev)) {
258 if (!dev->driver) {
259 if (!bus_match(dev,drv) && dev->driver)
260 devclass_add_device(dev);
262 put_device(dev);
265 return error;
268 static void detach(struct device * dev, struct device_driver * drv)
270 if (drv) {
271 sysfs_remove_link(&drv->kobj,dev->kobj.name);
272 list_del_init(&dev->driver_list);
273 devclass_remove_device(dev);
274 if (drv->remove)
275 drv->remove(dev);
276 dev->driver = NULL;
280 static void device_detach(struct device * dev)
282 detach(dev,dev->driver);
285 static void driver_detach(struct device_driver * drv)
287 struct list_head * entry, * next;
288 list_for_each_safe(entry,next,&drv->devices) {
289 struct device * dev = container_of(entry,struct device,driver_list);
290 if (get_device(dev)) {
291 detach(dev,drv);
292 put_device(dev);
299 * bus_add_device - add device to bus
300 * @dev: device being added
302 * Add the device to its bus's list of devices.
303 * Create a symlink in the bus's 'devices' directory to the
304 * device's physical location.
305 * Try and bind the device to a driver.
307 int bus_add_device(struct device * dev)
309 struct bus_type * bus = get_bus(dev->bus);
310 if (bus) {
311 down_write(&dev->bus->rwsem);
312 pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id);
313 list_add_tail(&dev->bus_list,&dev->bus->devices);
314 device_attach(dev);
315 up_write(&dev->bus->rwsem);
316 sysfs_create_link(&bus->devsubsys.kobj,&dev->kobj,dev->bus_id);
318 return 0;
322 * bus_remove_device - remove device from bus
323 * @dev: device to be removed
325 * Remove symlink from bus's directory.
326 * Delete device from bus's list.
328 void bus_remove_device(struct device * dev)
330 if (dev->bus) {
331 sysfs_remove_link(&dev->bus->devsubsys.kobj,dev->bus_id);
332 down_write(&dev->bus->rwsem);
333 pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
334 device_detach(dev);
335 list_del_init(&dev->bus_list);
336 up_write(&dev->bus->rwsem);
337 put_bus(dev->bus);
341 int bus_add_driver(struct device_driver * drv)
343 struct bus_type * bus = get_bus(drv->bus);
344 if (bus) {
345 down_write(&bus->rwsem);
346 pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
347 list_add_tail(&drv->bus_list,&bus->drivers);
348 driver_attach(drv);
349 up_write(&bus->rwsem);
351 return 0;
354 void bus_remove_driver(struct device_driver * drv)
356 if (drv->bus) {
357 down_write(&drv->bus->rwsem);
358 pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name);
359 driver_detach(drv);
360 list_del_init(&drv->bus_list);
361 up_write(&drv->bus->rwsem);
365 struct bus_type * get_bus(struct bus_type * bus)
367 struct bus_type * ret = bus;
368 spin_lock(&device_lock);
369 if (bus && bus->present && atomic_read(&bus->refcount))
370 atomic_inc(&bus->refcount);
371 else
372 ret = NULL;
373 spin_unlock(&device_lock);
374 return ret;
377 void put_bus(struct bus_type * bus)
379 if (!atomic_dec_and_lock(&bus->refcount,&device_lock))
380 return;
381 list_del_init(&bus->node);
382 spin_unlock(&device_lock);
383 WARN_ON(bus->present);
386 int bus_register(struct bus_type * bus)
388 init_rwsem(&bus->rwsem);
389 INIT_LIST_HEAD(&bus->devices);
390 INIT_LIST_HEAD(&bus->drivers);
391 atomic_set(&bus->refcount,2);
392 bus->present = 1;
394 strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
395 bus->subsys.parent = &bus_subsys;
396 subsystem_register(&bus->subsys);
398 snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");
399 bus->devsubsys.parent = &bus->subsys;
400 subsystem_register(&bus->devsubsys);
402 snprintf(bus->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers");
403 bus->drvsubsys.parent = &bus->subsys;
404 bus->drvsubsys.sysfs_ops = &driver_sysfs_ops;
405 subsystem_register(&bus->drvsubsys);
407 spin_lock(&device_lock);
408 list_add_tail(&bus->node,&bus_driver_list);
409 spin_unlock(&device_lock);
411 pr_debug("bus type '%s' registered\n",bus->name);
412 put_bus(bus);
413 return 0;
416 void bus_unregister(struct bus_type * bus)
418 spin_lock(&device_lock);
419 bus->present = 0;
420 spin_unlock(&device_lock);
422 pr_debug("bus %s: unregistering\n",bus->name);
423 subsystem_unregister(&bus->drvsubsys);
424 subsystem_unregister(&bus->devsubsys);
425 subsystem_unregister(&bus->subsys);
426 put_bus(bus);
429 static int __init bus_subsys_init(void)
431 return subsystem_register(&bus_subsys);
434 core_initcall(bus_subsys_init);
436 EXPORT_SYMBOL(bus_for_each_dev);
437 EXPORT_SYMBOL(bus_for_each_drv);
438 EXPORT_SYMBOL(bus_add_device);
439 EXPORT_SYMBOL(bus_remove_device);
440 EXPORT_SYMBOL(bus_register);
441 EXPORT_SYMBOL(bus_unregister);
442 EXPORT_SYMBOL(get_bus);
443 EXPORT_SYMBOL(put_bus);
445 EXPORT_SYMBOL(bus_create_file);
446 EXPORT_SYMBOL(bus_remove_file);