diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:34:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:35:13 -0500 |
commit | df8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch) | |
tree | bc3799a43e8b94fa84b32e37b1c124d5e4868f50 /drivers/base/bus.c | |
parent | 556a169dab38b5100df6f4a45b655dddd3db94c1 (diff) | |
parent | 4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas:
- Documentation updates (language translations and fixes, as
well as kobject and kset documenatation updates.)
- major kset/kobject/ktype rework and fixes. This cleans up the
kset and kobject and ktype relationship and architecture,
making sense of things now, and good documenation and samples
are provided for others to use. Also the attributes for
kobjects are much easier to handle now. This cleaned up a LOT
of code all through the kernel, making kobjects easier to use
if you want to.
- struct bus_type has been reworked to now handle the lifetime
rules properly, as the kobject is properly dynamic.
- struct driver has also been reworked, and now the lifetime
issues are resolved.
- the block subsystem has been converted to use struct device
now, and not "raw" kobjects. This patch has been in the -mm
tree for over a year now, and finally all the issues are
worked out with it. Older distros now properly work with new
kernels, and no userspace updates are needed at all.
- nozomi driver is added. This has also been in -mm for a long
time, and many people have asked for it to go in. It is now
in good enough shape to do so.
- lots of class_device conversions to use struct device instead.
The tree is almost all cleaned up now, only SCSI and IB is the
remaining code to fix up...
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits)
Driver core: coding style fixes
Kobject: fix coding style issues in kobject c files
Kobject: fix coding style issues in kobject.h
Driver core: fix coding style issues in device.h
spi: use class iteration api
scsi: use class iteration api
rtc: use class iteration api
power supply : use class iteration api
ieee1394: use class iteration api
Driver Core: add class iteration api
Driver core: Cleanup get_device_parent() in device_add() and device_move()
UIO: constify function pointer tables
Driver Core: constify the name passed to platform_device_register_simple
driver core: fix build with SYSFS=n
sysfs: make SYSFS_DEPRECATED depend on SYSFS
Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init
kobject: add sample code for how to use ksets/ktypes/kobjects
kobject: add sample code for how to use kobjects in a simple manner.
kobject: update the kobject/kset documentation
kobject: remove old, outdated documentation.
...
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r-- | drivers/base/bus.c | 501 |
1 files changed, 264 insertions, 237 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 9a19b071c573..f484495b2ad1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -17,14 +19,13 @@ | |||
17 | #include "power/power.h" | 19 | #include "power/power.h" |
18 | 20 | ||
19 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 21 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
20 | #define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj) | 22 | #define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) |
21 | 23 | ||
22 | /* | 24 | /* |
23 | * sysfs bindings for drivers | 25 | * sysfs bindings for drivers |
24 | */ | 26 | */ |
25 | 27 | ||
26 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) | 28 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) |
27 | #define to_driver(obj) container_of(obj, struct device_driver, kobj) | ||
28 | 29 | ||
29 | 30 | ||
30 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 31 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
@@ -32,37 +33,40 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
32 | 33 | ||
33 | static struct bus_type *bus_get(struct bus_type *bus) | 34 | static struct bus_type *bus_get(struct bus_type *bus) |
34 | { | 35 | { |
35 | return bus ? container_of(kset_get(&bus->subsys), | 36 | if (bus) { |
36 | struct bus_type, subsys) : NULL; | 37 | kset_get(&bus->p->subsys); |
38 | return bus; | ||
39 | } | ||
40 | return NULL; | ||
37 | } | 41 | } |
38 | 42 | ||
39 | static void bus_put(struct bus_type *bus) | 43 | static void bus_put(struct bus_type *bus) |
40 | { | 44 | { |
41 | kset_put(&bus->subsys); | 45 | if (bus) |
46 | kset_put(&bus->p->subsys); | ||
42 | } | 47 | } |
43 | 48 | ||
44 | static ssize_t | 49 | static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr, |
45 | drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 50 | char *buf) |
46 | { | 51 | { |
47 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 52 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
48 | struct device_driver * drv = to_driver(kobj); | 53 | struct driver_private *drv_priv = to_driver(kobj); |
49 | ssize_t ret = -EIO; | 54 | ssize_t ret = -EIO; |
50 | 55 | ||
51 | if (drv_attr->show) | 56 | if (drv_attr->show) |
52 | ret = drv_attr->show(drv, buf); | 57 | ret = drv_attr->show(drv_priv->driver, buf); |
53 | return ret; | 58 | return ret; |
54 | } | 59 | } |
55 | 60 | ||
56 | static ssize_t | 61 | static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, |
57 | drv_attr_store(struct kobject * kobj, struct attribute * attr, | 62 | const char *buf, size_t count) |
58 | const char * buf, size_t count) | ||
59 | { | 63 | { |
60 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 64 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
61 | struct device_driver * drv = to_driver(kobj); | 65 | struct driver_private *drv_priv = to_driver(kobj); |
62 | ssize_t ret = -EIO; | 66 | ssize_t ret = -EIO; |
63 | 67 | ||
64 | if (drv_attr->store) | 68 | if (drv_attr->store) |
65 | ret = drv_attr->store(drv, buf, count); | 69 | ret = drv_attr->store(drv_priv->driver, buf, count); |
66 | return ret; | 70 | return ret; |
67 | } | 71 | } |
68 | 72 | ||
@@ -71,22 +75,12 @@ static struct sysfs_ops driver_sysfs_ops = { | |||
71 | .store = drv_attr_store, | 75 | .store = drv_attr_store, |
72 | }; | 76 | }; |
73 | 77 | ||
74 | 78 | static void driver_release(struct kobject *kobj) | |
75 | static void driver_release(struct kobject * kobj) | ||
76 | { | 79 | { |
77 | /* | 80 | struct driver_private *drv_priv = to_driver(kobj); |
78 | * Yes this is an empty release function, it is this way because struct | 81 | |
79 | * device is always a static object, not a dynamic one. Yes, this is | 82 | pr_debug("driver: '%s': %s\n", kobject_name(kobj), __FUNCTION__); |
80 | * not nice and bad, but remember, drivers are code, reference counted | 83 | kfree(drv_priv); |
81 | * by the module count, not a device, which is really data. And yes, | ||
82 | * in the future I do want to have all drivers be created dynamically, | ||
83 | * and am working toward that goal, but it will take a bit longer... | ||
84 | * | ||
85 | * But do not let this example give _anyone_ the idea that they can | ||
86 | * create a release function without any code in it at all, to do that | ||
87 | * is almost always wrong. If you have any questions about this, | ||
88 | * please send an email to <greg@kroah.com> | ||
89 | */ | ||
90 | } | 84 | } |
91 | 85 | ||
92 | static struct kobj_type driver_ktype = { | 86 | static struct kobj_type driver_ktype = { |
@@ -94,34 +88,30 @@ static struct kobj_type driver_ktype = { | |||
94 | .release = driver_release, | 88 | .release = driver_release, |
95 | }; | 89 | }; |
96 | 90 | ||
97 | |||
98 | /* | 91 | /* |
99 | * sysfs bindings for buses | 92 | * sysfs bindings for buses |
100 | */ | 93 | */ |
101 | 94 | static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, | |
102 | 95 | char *buf) | |
103 | static ssize_t | ||
104 | bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | ||
105 | { | 96 | { |
106 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 97 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
107 | struct bus_type * bus = to_bus(kobj); | 98 | struct bus_type_private *bus_priv = to_bus(kobj); |
108 | ssize_t ret = 0; | 99 | ssize_t ret = 0; |
109 | 100 | ||
110 | if (bus_attr->show) | 101 | if (bus_attr->show) |
111 | ret = bus_attr->show(bus, buf); | 102 | ret = bus_attr->show(bus_priv->bus, buf); |
112 | return ret; | 103 | return ret; |
113 | } | 104 | } |
114 | 105 | ||
115 | static ssize_t | 106 | static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, |
116 | bus_attr_store(struct kobject * kobj, struct attribute * attr, | 107 | const char *buf, size_t count) |
117 | const char * buf, size_t count) | ||
118 | { | 108 | { |
119 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 109 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
120 | struct bus_type * bus = to_bus(kobj); | 110 | struct bus_type_private *bus_priv = to_bus(kobj); |
121 | ssize_t ret = 0; | 111 | ssize_t ret = 0; |
122 | 112 | ||
123 | if (bus_attr->store) | 113 | if (bus_attr->store) |
124 | ret = bus_attr->store(bus, buf, count); | 114 | ret = bus_attr->store(bus_priv->bus, buf, count); |
125 | return ret; | 115 | return ret; |
126 | } | 116 | } |
127 | 117 | ||
@@ -130,24 +120,26 @@ static struct sysfs_ops bus_sysfs_ops = { | |||
130 | .store = bus_attr_store, | 120 | .store = bus_attr_store, |
131 | }; | 121 | }; |
132 | 122 | ||
133 | int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) | 123 | int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) |
134 | { | 124 | { |
135 | int error; | 125 | int error; |
136 | if (bus_get(bus)) { | 126 | if (bus_get(bus)) { |
137 | error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); | 127 | error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); |
138 | bus_put(bus); | 128 | bus_put(bus); |
139 | } else | 129 | } else |
140 | error = -EINVAL; | 130 | error = -EINVAL; |
141 | return error; | 131 | return error; |
142 | } | 132 | } |
133 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
143 | 134 | ||
144 | void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) | 135 | void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr) |
145 | { | 136 | { |
146 | if (bus_get(bus)) { | 137 | if (bus_get(bus)) { |
147 | sysfs_remove_file(&bus->subsys.kobj, &attr->attr); | 138 | sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); |
148 | bus_put(bus); | 139 | bus_put(bus); |
149 | } | 140 | } |
150 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||
151 | 143 | ||
152 | static struct kobj_type bus_ktype = { | 144 | static struct kobj_type bus_ktype = { |
153 | .sysfs_ops = &bus_sysfs_ops, | 145 | .sysfs_ops = &bus_sysfs_ops, |
@@ -166,7 +158,7 @@ static struct kset_uevent_ops bus_uevent_ops = { | |||
166 | .filter = bus_uevent_filter, | 158 | .filter = bus_uevent_filter, |
167 | }; | 159 | }; |
168 | 160 | ||
169 | static decl_subsys(bus, &bus_ktype, &bus_uevent_ops); | 161 | static struct kset *bus_kset; |
170 | 162 | ||
171 | 163 | ||
172 | #ifdef CONFIG_HOTPLUG | 164 | #ifdef CONFIG_HOTPLUG |
@@ -224,10 +216,13 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
224 | if (dev->parent) | 216 | if (dev->parent) |
225 | up(&dev->parent->sem); | 217 | up(&dev->parent->sem); |
226 | 218 | ||
227 | if (err > 0) /* success */ | 219 | if (err > 0) { |
220 | /* success */ | ||
228 | err = count; | 221 | err = count; |
229 | else if (err == 0) /* driver didn't accept device */ | 222 | } else if (err == 0) { |
223 | /* driver didn't accept device */ | ||
230 | err = -ENODEV; | 224 | err = -ENODEV; |
225 | } | ||
231 | } | 226 | } |
232 | put_device(dev); | 227 | put_device(dev); |
233 | bus_put(bus); | 228 | bus_put(bus); |
@@ -237,16 +232,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | |||
237 | 232 | ||
238 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) | 233 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) |
239 | { | 234 | { |
240 | return sprintf(buf, "%d\n", bus->drivers_autoprobe); | 235 | return sprintf(buf, "%d\n", bus->p->drivers_autoprobe); |
241 | } | 236 | } |
242 | 237 | ||
243 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, | 238 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, |
244 | const char *buf, size_t count) | 239 | const char *buf, size_t count) |
245 | { | 240 | { |
246 | if (buf[0] == '0') | 241 | if (buf[0] == '0') |
247 | bus->drivers_autoprobe = 0; | 242 | bus->p->drivers_autoprobe = 0; |
248 | else | 243 | else |
249 | bus->drivers_autoprobe = 1; | 244 | bus->p->drivers_autoprobe = 1; |
250 | return count; | 245 | return count; |
251 | } | 246 | } |
252 | 247 | ||
@@ -264,49 +259,49 @@ static ssize_t store_drivers_probe(struct bus_type *bus, | |||
264 | } | 259 | } |
265 | #endif | 260 | #endif |
266 | 261 | ||
267 | static struct device * next_device(struct klist_iter * i) | 262 | static struct device *next_device(struct klist_iter *i) |
268 | { | 263 | { |
269 | struct klist_node * n = klist_next(i); | 264 | struct klist_node *n = klist_next(i); |
270 | return n ? container_of(n, struct device, knode_bus) : NULL; | 265 | return n ? container_of(n, struct device, knode_bus) : NULL; |
271 | } | 266 | } |
272 | 267 | ||
273 | /** | 268 | /** |
274 | * bus_for_each_dev - device iterator. | 269 | * bus_for_each_dev - device iterator. |
275 | * @bus: bus type. | 270 | * @bus: bus type. |
276 | * @start: device to start iterating from. | 271 | * @start: device to start iterating from. |
277 | * @data: data for the callback. | 272 | * @data: data for the callback. |
278 | * @fn: function to be called for each device. | 273 | * @fn: function to be called for each device. |
279 | * | 274 | * |
280 | * Iterate over @bus's list of devices, and call @fn for each, | 275 | * Iterate over @bus's list of devices, and call @fn for each, |
281 | * passing it @data. If @start is not NULL, we use that device to | 276 | * passing it @data. If @start is not NULL, we use that device to |
282 | * begin iterating from. | 277 | * begin iterating from. |
283 | * | 278 | * |
284 | * We check the return of @fn each time. If it returns anything | 279 | * We check the return of @fn each time. If it returns anything |
285 | * other than 0, we break out and return that value. | 280 | * other than 0, we break out and return that value. |
286 | * | 281 | * |
287 | * NOTE: The device that returns a non-zero value is not retained | 282 | * NOTE: The device that returns a non-zero value is not retained |
288 | * in any way, nor is its refcount incremented. If the caller needs | 283 | * in any way, nor is its refcount incremented. If the caller needs |
289 | * to retain this data, it should do, and increment the reference | 284 | * to retain this data, it should do, and increment the reference |
290 | * count in the supplied callback. | 285 | * count in the supplied callback. |
291 | */ | 286 | */ |
292 | 287 | int bus_for_each_dev(struct bus_type *bus, struct device *start, | |
293 | int bus_for_each_dev(struct bus_type * bus, struct device * start, | 288 | void *data, int (*fn)(struct device *, void *)) |
294 | void * data, int (*fn)(struct device *, void *)) | ||
295 | { | 289 | { |
296 | struct klist_iter i; | 290 | struct klist_iter i; |
297 | struct device * dev; | 291 | struct device *dev; |
298 | int error = 0; | 292 | int error = 0; |
299 | 293 | ||
300 | if (!bus) | 294 | if (!bus) |
301 | return -EINVAL; | 295 | return -EINVAL; |
302 | 296 | ||
303 | klist_iter_init_node(&bus->klist_devices, &i, | 297 | klist_iter_init_node(&bus->p->klist_devices, &i, |
304 | (start ? &start->knode_bus : NULL)); | 298 | (start ? &start->knode_bus : NULL)); |
305 | while ((dev = next_device(&i)) && !error) | 299 | while ((dev = next_device(&i)) && !error) |
306 | error = fn(dev, data); | 300 | error = fn(dev, data); |
307 | klist_iter_exit(&i); | 301 | klist_iter_exit(&i); |
308 | return error; | 302 | return error; |
309 | } | 303 | } |
304 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | ||
310 | 305 | ||
311 | /** | 306 | /** |
312 | * bus_find_device - device iterator for locating a particular device. | 307 | * bus_find_device - device iterator for locating a particular device. |
@@ -323,9 +318,9 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, | |||
323 | * if it does. If the callback returns non-zero, this function will | 318 | * if it does. If the callback returns non-zero, this function will |
324 | * return to the caller and not iterate over any more devices. | 319 | * return to the caller and not iterate over any more devices. |
325 | */ | 320 | */ |
326 | struct device * bus_find_device(struct bus_type *bus, | 321 | struct device *bus_find_device(struct bus_type *bus, |
327 | struct device *start, void *data, | 322 | struct device *start, void *data, |
328 | int (*match)(struct device *, void *)) | 323 | int (*match)(struct device *dev, void *data)) |
329 | { | 324 | { |
330 | struct klist_iter i; | 325 | struct klist_iter i; |
331 | struct device *dev; | 326 | struct device *dev; |
@@ -333,7 +328,7 @@ struct device * bus_find_device(struct bus_type *bus, | |||
333 | if (!bus) | 328 | if (!bus) |
334 | return NULL; | 329 | return NULL; |
335 | 330 | ||
336 | klist_iter_init_node(&bus->klist_devices, &i, | 331 | klist_iter_init_node(&bus->p->klist_devices, &i, |
337 | (start ? &start->knode_bus : NULL)); | 332 | (start ? &start->knode_bus : NULL)); |
338 | while ((dev = next_device(&i))) | 333 | while ((dev = next_device(&i))) |
339 | if (match(dev, data) && get_device(dev)) | 334 | if (match(dev, data) && get_device(dev)) |
@@ -341,51 +336,57 @@ struct device * bus_find_device(struct bus_type *bus, | |||
341 | klist_iter_exit(&i); | 336 | klist_iter_exit(&i); |
342 | return dev; | 337 | return dev; |
343 | } | 338 | } |
339 | EXPORT_SYMBOL_GPL(bus_find_device); | ||
344 | 340 | ||
345 | 341 | static struct device_driver *next_driver(struct klist_iter *i) | |
346 | static struct device_driver * next_driver(struct klist_iter * i) | ||
347 | { | 342 | { |
348 | struct klist_node * n = klist_next(i); | 343 | struct klist_node *n = klist_next(i); |
349 | return n ? container_of(n, struct device_driver, knode_bus) : NULL; | 344 | struct driver_private *drv_priv; |
345 | |||
346 | if (n) { | ||
347 | drv_priv = container_of(n, struct driver_private, knode_bus); | ||
348 | return drv_priv->driver; | ||
349 | } | ||
350 | return NULL; | ||
350 | } | 351 | } |
351 | 352 | ||
352 | /** | 353 | /** |
353 | * bus_for_each_drv - driver iterator | 354 | * bus_for_each_drv - driver iterator |
354 | * @bus: bus we're dealing with. | 355 | * @bus: bus we're dealing with. |
355 | * @start: driver to start iterating on. | 356 | * @start: driver to start iterating on. |
356 | * @data: data to pass to the callback. | 357 | * @data: data to pass to the callback. |
357 | * @fn: function to call for each driver. | 358 | * @fn: function to call for each driver. |
358 | * | 359 | * |
359 | * This is nearly identical to the device iterator above. | 360 | * This is nearly identical to the device iterator above. |
360 | * We iterate over each driver that belongs to @bus, and call | 361 | * We iterate over each driver that belongs to @bus, and call |
361 | * @fn for each. If @fn returns anything but 0, we break out | 362 | * @fn for each. If @fn returns anything but 0, we break out |
362 | * and return it. If @start is not NULL, we use it as the head | 363 | * and return it. If @start is not NULL, we use it as the head |
363 | * of the list. | 364 | * of the list. |
364 | * | 365 | * |
365 | * NOTE: we don't return the driver that returns a non-zero | 366 | * NOTE: we don't return the driver that returns a non-zero |
366 | * value, nor do we leave the reference count incremented for that | 367 | * value, nor do we leave the reference count incremented for that |
367 | * driver. If the caller needs to know that info, it must set it | 368 | * driver. If the caller needs to know that info, it must set it |
368 | * in the callback. It must also be sure to increment the refcount | 369 | * in the callback. It must also be sure to increment the refcount |
369 | * so it doesn't disappear before returning to the caller. | 370 | * so it doesn't disappear before returning to the caller. |
370 | */ | 371 | */ |
371 | 372 | int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, | |
372 | int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, | 373 | void *data, int (*fn)(struct device_driver *, void *)) |
373 | void * data, int (*fn)(struct device_driver *, void *)) | ||
374 | { | 374 | { |
375 | struct klist_iter i; | 375 | struct klist_iter i; |
376 | struct device_driver * drv; | 376 | struct device_driver *drv; |
377 | int error = 0; | 377 | int error = 0; |
378 | 378 | ||
379 | if (!bus) | 379 | if (!bus) |
380 | return -EINVAL; | 380 | return -EINVAL; |
381 | 381 | ||
382 | klist_iter_init_node(&bus->klist_drivers, &i, | 382 | klist_iter_init_node(&bus->p->klist_drivers, &i, |
383 | start ? &start->knode_bus : NULL); | 383 | start ? &start->p->knode_bus : NULL); |
384 | while ((drv = next_driver(&i)) && !error) | 384 | while ((drv = next_driver(&i)) && !error) |
385 | error = fn(drv, data); | 385 | error = fn(drv, data); |
386 | klist_iter_exit(&i); | 386 | klist_iter_exit(&i); |
387 | return error; | 387 | return error; |
388 | } | 388 | } |
389 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | ||
389 | 390 | ||
390 | static int device_add_attrs(struct bus_type *bus, struct device *dev) | 391 | static int device_add_attrs(struct bus_type *bus, struct device *dev) |
391 | { | 392 | { |
@@ -396,7 +397,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
396 | return 0; | 397 | return 0; |
397 | 398 | ||
398 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { | 399 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { |
399 | error = device_create_file(dev,&bus->dev_attrs[i]); | 400 | error = device_create_file(dev, &bus->dev_attrs[i]); |
400 | if (error) { | 401 | if (error) { |
401 | while (--i >= 0) | 402 | while (--i >= 0) |
402 | device_remove_file(dev, &bus->dev_attrs[i]); | 403 | device_remove_file(dev, &bus->dev_attrs[i]); |
@@ -406,13 +407,13 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
406 | return error; | 407 | return error; |
407 | } | 408 | } |
408 | 409 | ||
409 | static void device_remove_attrs(struct bus_type * bus, struct device * dev) | 410 | static void device_remove_attrs(struct bus_type *bus, struct device *dev) |
410 | { | 411 | { |
411 | int i; | 412 | int i; |
412 | 413 | ||
413 | if (bus->dev_attrs) { | 414 | if (bus->dev_attrs) { |
414 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) | 415 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) |
415 | device_remove_file(dev,&bus->dev_attrs[i]); | 416 | device_remove_file(dev, &bus->dev_attrs[i]); |
416 | } | 417 | } |
417 | } | 418 | } |
418 | 419 | ||
@@ -420,7 +421,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) | |||
420 | static int make_deprecated_bus_links(struct device *dev) | 421 | static int make_deprecated_bus_links(struct device *dev) |
421 | { | 422 | { |
422 | return sysfs_create_link(&dev->kobj, | 423 | return sysfs_create_link(&dev->kobj, |
423 | &dev->bus->subsys.kobj, "bus"); | 424 | &dev->bus->p->subsys.kobj, "bus"); |
424 | } | 425 | } |
425 | 426 | ||
426 | static void remove_deprecated_bus_links(struct device *dev) | 427 | static void remove_deprecated_bus_links(struct device *dev) |
@@ -433,28 +434,28 @@ static inline void remove_deprecated_bus_links(struct device *dev) { } | |||
433 | #endif | 434 | #endif |
434 | 435 | ||
435 | /** | 436 | /** |
436 | * bus_add_device - add device to bus | 437 | * bus_add_device - add device to bus |
437 | * @dev: device being added | 438 | * @dev: device being added |
438 | * | 439 | * |
439 | * - Add the device to its bus's list of devices. | 440 | * - Add the device to its bus's list of devices. |
440 | * - Create link to device's bus. | 441 | * - Create link to device's bus. |
441 | */ | 442 | */ |
442 | int bus_add_device(struct device * dev) | 443 | int bus_add_device(struct device *dev) |
443 | { | 444 | { |
444 | struct bus_type * bus = bus_get(dev->bus); | 445 | struct bus_type *bus = bus_get(dev->bus); |
445 | int error = 0; | 446 | int error = 0; |
446 | 447 | ||
447 | if (bus) { | 448 | if (bus) { |
448 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 449 | pr_debug("bus: '%s': add device %s\n", bus->name, dev->bus_id); |
449 | error = device_add_attrs(bus, dev); | 450 | error = device_add_attrs(bus, dev); |
450 | if (error) | 451 | if (error) |
451 | goto out_put; | 452 | goto out_put; |
452 | error = sysfs_create_link(&bus->devices.kobj, | 453 | error = sysfs_create_link(&bus->p->devices_kset->kobj, |
453 | &dev->kobj, dev->bus_id); | 454 | &dev->kobj, dev->bus_id); |
454 | if (error) | 455 | if (error) |
455 | goto out_id; | 456 | goto out_id; |
456 | error = sysfs_create_link(&dev->kobj, | 457 | error = sysfs_create_link(&dev->kobj, |
457 | &dev->bus->subsys.kobj, "subsystem"); | 458 | &dev->bus->p->subsys.kobj, "subsystem"); |
458 | if (error) | 459 | if (error) |
459 | goto out_subsys; | 460 | goto out_subsys; |
460 | error = make_deprecated_bus_links(dev); | 461 | error = make_deprecated_bus_links(dev); |
@@ -466,7 +467,7 @@ int bus_add_device(struct device * dev) | |||
466 | out_deprecated: | 467 | out_deprecated: |
467 | sysfs_remove_link(&dev->kobj, "subsystem"); | 468 | sysfs_remove_link(&dev->kobj, "subsystem"); |
468 | out_subsys: | 469 | out_subsys: |
469 | sysfs_remove_link(&bus->devices.kobj, dev->bus_id); | 470 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev->bus_id); |
470 | out_id: | 471 | out_id: |
471 | device_remove_attrs(bus, dev); | 472 | device_remove_attrs(bus, dev); |
472 | out_put: | 473 | out_put: |
@@ -475,56 +476,58 @@ out_put: | |||
475 | } | 476 | } |
476 | 477 | ||
477 | /** | 478 | /** |
478 | * bus_attach_device - add device to bus | 479 | * bus_attach_device - add device to bus |
479 | * @dev: device tried to attach to a driver | 480 | * @dev: device tried to attach to a driver |
480 | * | 481 | * |
481 | * - Add device to bus's list of devices. | 482 | * - Add device to bus's list of devices. |
482 | * - Try to attach to driver. | 483 | * - Try to attach to driver. |
483 | */ | 484 | */ |
484 | void bus_attach_device(struct device * dev) | 485 | void bus_attach_device(struct device *dev) |
485 | { | 486 | { |
486 | struct bus_type *bus = dev->bus; | 487 | struct bus_type *bus = dev->bus; |
487 | int ret = 0; | 488 | int ret = 0; |
488 | 489 | ||
489 | if (bus) { | 490 | if (bus) { |
490 | dev->is_registered = 1; | 491 | dev->is_registered = 1; |
491 | if (bus->drivers_autoprobe) | 492 | if (bus->p->drivers_autoprobe) |
492 | ret = device_attach(dev); | 493 | ret = device_attach(dev); |
493 | WARN_ON(ret < 0); | 494 | WARN_ON(ret < 0); |
494 | if (ret >= 0) | 495 | if (ret >= 0) |
495 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); | 496 | klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); |
496 | else | 497 | else |
497 | dev->is_registered = 0; | 498 | dev->is_registered = 0; |
498 | } | 499 | } |
499 | } | 500 | } |
500 | 501 | ||
501 | /** | 502 | /** |
502 | * bus_remove_device - remove device from bus | 503 | * bus_remove_device - remove device from bus |
503 | * @dev: device to be removed | 504 | * @dev: device to be removed |
504 | * | 505 | * |
505 | * - Remove symlink from bus's directory. | 506 | * - Remove symlink from bus's directory. |
506 | * - Delete device from bus's list. | 507 | * - Delete device from bus's list. |
507 | * - Detach from its driver. | 508 | * - Detach from its driver. |
508 | * - Drop reference taken in bus_add_device(). | 509 | * - Drop reference taken in bus_add_device(). |
509 | */ | 510 | */ |
510 | void bus_remove_device(struct device * dev) | 511 | void bus_remove_device(struct device *dev) |
511 | { | 512 | { |
512 | if (dev->bus) { | 513 | if (dev->bus) { |
513 | sysfs_remove_link(&dev->kobj, "subsystem"); | 514 | sysfs_remove_link(&dev->kobj, "subsystem"); |
514 | remove_deprecated_bus_links(dev); | 515 | remove_deprecated_bus_links(dev); |
515 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 516 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
517 | dev->bus_id); | ||
516 | device_remove_attrs(dev->bus, dev); | 518 | device_remove_attrs(dev->bus, dev); |
517 | if (dev->is_registered) { | 519 | if (dev->is_registered) { |
518 | dev->is_registered = 0; | 520 | dev->is_registered = 0; |
519 | klist_del(&dev->knode_bus); | 521 | klist_del(&dev->knode_bus); |
520 | } | 522 | } |
521 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 523 | pr_debug("bus: '%s': remove device %s\n", |
524 | dev->bus->name, dev->bus_id); | ||
522 | device_release_driver(dev); | 525 | device_release_driver(dev); |
523 | bus_put(dev->bus); | 526 | bus_put(dev->bus); |
524 | } | 527 | } |
525 | } | 528 | } |
526 | 529 | ||
527 | static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | 530 | static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) |
528 | { | 531 | { |
529 | int error = 0; | 532 | int error = 0; |
530 | int i; | 533 | int i; |
@@ -533,19 +536,19 @@ static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | |||
533 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { | 536 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { |
534 | error = driver_create_file(drv, &bus->drv_attrs[i]); | 537 | error = driver_create_file(drv, &bus->drv_attrs[i]); |
535 | if (error) | 538 | if (error) |
536 | goto Err; | 539 | goto err; |
537 | } | 540 | } |
538 | } | 541 | } |
539 | Done: | 542 | done: |
540 | return error; | 543 | return error; |
541 | Err: | 544 | err: |
542 | while (--i >= 0) | 545 | while (--i >= 0) |
543 | driver_remove_file(drv, &bus->drv_attrs[i]); | 546 | driver_remove_file(drv, &bus->drv_attrs[i]); |
544 | goto Done; | 547 | goto done; |
545 | } | 548 | } |
546 | 549 | ||
547 | 550 | static void driver_remove_attrs(struct bus_type *bus, | |
548 | static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv) | 551 | struct device_driver *drv) |
549 | { | 552 | { |
550 | int i; | 553 | int i; |
551 | 554 | ||
@@ -616,39 +619,46 @@ static ssize_t driver_uevent_store(struct device_driver *drv, | |||
616 | enum kobject_action action; | 619 | enum kobject_action action; |
617 | 620 | ||
618 | if (kobject_action_type(buf, count, &action) == 0) | 621 | if (kobject_action_type(buf, count, &action) == 0) |
619 | kobject_uevent(&drv->kobj, action); | 622 | kobject_uevent(&drv->p->kobj, action); |
620 | return count; | 623 | return count; |
621 | } | 624 | } |
622 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | 625 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); |
623 | 626 | ||
624 | /** | 627 | /** |
625 | * bus_add_driver - Add a driver to the bus. | 628 | * bus_add_driver - Add a driver to the bus. |
626 | * @drv: driver. | 629 | * @drv: driver. |
627 | * | ||
628 | */ | 630 | */ |
629 | int bus_add_driver(struct device_driver *drv) | 631 | int bus_add_driver(struct device_driver *drv) |
630 | { | 632 | { |
631 | struct bus_type * bus = bus_get(drv->bus); | 633 | struct bus_type *bus; |
634 | struct driver_private *priv; | ||
632 | int error = 0; | 635 | int error = 0; |
633 | 636 | ||
637 | bus = bus_get(drv->bus); | ||
634 | if (!bus) | 638 | if (!bus) |
635 | return -EINVAL; | 639 | return -EINVAL; |
636 | 640 | ||
637 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 641 | pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); |
638 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 642 | |
639 | if (error) | 643 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
640 | goto out_put_bus; | 644 | if (!priv) |
641 | drv->kobj.kset = &bus->drivers; | 645 | return -ENOMEM; |
642 | error = kobject_register(&drv->kobj); | 646 | |
647 | klist_init(&priv->klist_devices, NULL, NULL); | ||
648 | priv->driver = drv; | ||
649 | drv->p = priv; | ||
650 | priv->kobj.kset = bus->p->drivers_kset; | ||
651 | error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, | ||
652 | "%s", drv->name); | ||
643 | if (error) | 653 | if (error) |
644 | goto out_put_bus; | 654 | goto out_put_bus; |
645 | 655 | ||
646 | if (drv->bus->drivers_autoprobe) { | 656 | if (drv->bus->p->drivers_autoprobe) { |
647 | error = driver_attach(drv); | 657 | error = driver_attach(drv); |
648 | if (error) | 658 | if (error) |
649 | goto out_unregister; | 659 | goto out_unregister; |
650 | } | 660 | } |
651 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 661 | klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); |
652 | module_add_driver(drv->owner, drv); | 662 | module_add_driver(drv->owner, drv); |
653 | 663 | ||
654 | error = driver_create_file(drv, &driver_attr_uevent); | 664 | error = driver_create_file(drv, &driver_attr_uevent); |
@@ -669,24 +679,24 @@ int bus_add_driver(struct device_driver *drv) | |||
669 | __FUNCTION__, drv->name); | 679 | __FUNCTION__, drv->name); |
670 | } | 680 | } |
671 | 681 | ||
682 | kobject_uevent(&priv->kobj, KOBJ_ADD); | ||
672 | return error; | 683 | return error; |
673 | out_unregister: | 684 | out_unregister: |
674 | kobject_unregister(&drv->kobj); | 685 | kobject_put(&priv->kobj); |
675 | out_put_bus: | 686 | out_put_bus: |
676 | bus_put(bus); | 687 | bus_put(bus); |
677 | return error; | 688 | return error; |
678 | } | 689 | } |
679 | 690 | ||
680 | /** | 691 | /** |
681 | * bus_remove_driver - delete driver from bus's knowledge. | 692 | * bus_remove_driver - delete driver from bus's knowledge. |
682 | * @drv: driver. | 693 | * @drv: driver. |
683 | * | 694 | * |
684 | * Detach the driver from the devices it controls, and remove | 695 | * Detach the driver from the devices it controls, and remove |
685 | * it from its bus's list of drivers. Finally, we drop the reference | 696 | * it from its bus's list of drivers. Finally, we drop the reference |
686 | * to the bus we took in bus_add_driver(). | 697 | * to the bus we took in bus_add_driver(). |
687 | */ | 698 | */ |
688 | 699 | void bus_remove_driver(struct device_driver *drv) | |
689 | void bus_remove_driver(struct device_driver * drv) | ||
690 | { | 700 | { |
691 | if (!drv->bus) | 701 | if (!drv->bus) |
692 | return; | 702 | return; |
@@ -694,18 +704,17 @@ void bus_remove_driver(struct device_driver * drv) | |||
694 | remove_bind_files(drv); | 704 | remove_bind_files(drv); |
695 | driver_remove_attrs(drv->bus, drv); | 705 | driver_remove_attrs(drv->bus, drv); |
696 | driver_remove_file(drv, &driver_attr_uevent); | 706 | driver_remove_file(drv, &driver_attr_uevent); |
697 | klist_remove(&drv->knode_bus); | 707 | klist_remove(&drv->p->knode_bus); |
698 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 708 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); |
699 | driver_detach(drv); | 709 | driver_detach(drv); |
700 | module_remove_driver(drv); | 710 | module_remove_driver(drv); |
701 | kobject_unregister(&drv->kobj); | 711 | kobject_put(&drv->p->kobj); |
702 | bus_put(drv->bus); | 712 | bus_put(drv->bus); |
703 | } | 713 | } |
704 | 714 | ||
705 | |||
706 | /* Helper for bus_rescan_devices's iter */ | 715 | /* Helper for bus_rescan_devices's iter */ |
707 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 716 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
708 | void *data) | 717 | void *data) |
709 | { | 718 | { |
710 | int ret = 0; | 719 | int ret = 0; |
711 | 720 | ||
@@ -727,10 +736,11 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
727 | * attached and rescan it against existing drivers to see if it matches | 736 | * attached and rescan it against existing drivers to see if it matches |
728 | * any by calling device_attach() for the unbound devices. | 737 | * any by calling device_attach() for the unbound devices. |
729 | */ | 738 | */ |
730 | int bus_rescan_devices(struct bus_type * bus) | 739 | int bus_rescan_devices(struct bus_type *bus) |
731 | { | 740 | { |
732 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); | 741 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
733 | } | 742 | } |
743 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | ||
734 | 744 | ||
735 | /** | 745 | /** |
736 | * device_reprobe - remove driver for a device and probe for a new driver | 746 | * device_reprobe - remove driver for a device and probe for a new driver |
@@ -755,55 +765,55 @@ int device_reprobe(struct device *dev) | |||
755 | EXPORT_SYMBOL_GPL(device_reprobe); | 765 | EXPORT_SYMBOL_GPL(device_reprobe); |
756 | 766 | ||
757 | /** | 767 | /** |
758 | * find_bus - locate bus by name. | 768 | * find_bus - locate bus by name. |
759 | * @name: name of bus. | 769 | * @name: name of bus. |
760 | * | 770 | * |
761 | * Call kset_find_obj() to iterate over list of buses to | 771 | * Call kset_find_obj() to iterate over list of buses to |
762 | * find a bus by name. Return bus if found. | 772 | * find a bus by name. Return bus if found. |
763 | * | 773 | * |
764 | * Note that kset_find_obj increments bus' reference count. | 774 | * Note that kset_find_obj increments bus' reference count. |
765 | */ | 775 | */ |
766 | #if 0 | 776 | #if 0 |
767 | struct bus_type * find_bus(char * name) | 777 | struct bus_type *find_bus(char *name) |
768 | { | 778 | { |
769 | struct kobject * k = kset_find_obj(&bus_subsys.kset, name); | 779 | struct kobject *k = kset_find_obj(bus_kset, name); |
770 | return k ? to_bus(k) : NULL; | 780 | return k ? to_bus(k) : NULL; |
771 | } | 781 | } |
772 | #endif /* 0 */ | 782 | #endif /* 0 */ |
773 | 783 | ||
774 | 784 | ||
775 | /** | 785 | /** |
776 | * bus_add_attrs - Add default attributes for this bus. | 786 | * bus_add_attrs - Add default attributes for this bus. |
777 | * @bus: Bus that has just been registered. | 787 | * @bus: Bus that has just been registered. |
778 | */ | 788 | */ |
779 | 789 | ||
780 | static int bus_add_attrs(struct bus_type * bus) | 790 | static int bus_add_attrs(struct bus_type *bus) |
781 | { | 791 | { |
782 | int error = 0; | 792 | int error = 0; |
783 | int i; | 793 | int i; |
784 | 794 | ||
785 | if (bus->bus_attrs) { | 795 | if (bus->bus_attrs) { |
786 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 796 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { |
787 | error = bus_create_file(bus,&bus->bus_attrs[i]); | 797 | error = bus_create_file(bus, &bus->bus_attrs[i]); |
788 | if (error) | 798 | if (error) |
789 | goto Err; | 799 | goto err; |
790 | } | 800 | } |
791 | } | 801 | } |
792 | Done: | 802 | done: |
793 | return error; | 803 | return error; |
794 | Err: | 804 | err: |
795 | while (--i >= 0) | 805 | while (--i >= 0) |
796 | bus_remove_file(bus,&bus->bus_attrs[i]); | 806 | bus_remove_file(bus, &bus->bus_attrs[i]); |
797 | goto Done; | 807 | goto done; |
798 | } | 808 | } |
799 | 809 | ||
800 | static void bus_remove_attrs(struct bus_type * bus) | 810 | static void bus_remove_attrs(struct bus_type *bus) |
801 | { | 811 | { |
802 | int i; | 812 | int i; |
803 | 813 | ||
804 | if (bus->bus_attrs) { | 814 | if (bus->bus_attrs) { |
805 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) | 815 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) |
806 | bus_remove_file(bus,&bus->bus_attrs[i]); | 816 | bus_remove_file(bus, &bus->bus_attrs[i]); |
807 | } | 817 | } |
808 | } | 818 | } |
809 | 819 | ||
@@ -827,32 +837,42 @@ static ssize_t bus_uevent_store(struct bus_type *bus, | |||
827 | enum kobject_action action; | 837 | enum kobject_action action; |
828 | 838 | ||
829 | if (kobject_action_type(buf, count, &action) == 0) | 839 | if (kobject_action_type(buf, count, &action) == 0) |
830 | kobject_uevent(&bus->subsys.kobj, action); | 840 | kobject_uevent(&bus->p->subsys.kobj, action); |
831 | return count; | 841 | return count; |
832 | } | 842 | } |
833 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | 843 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); |
834 | 844 | ||
835 | /** | 845 | /** |
836 | * bus_register - register a bus with the system. | 846 | * bus_register - register a bus with the system. |
837 | * @bus: bus. | 847 | * @bus: bus. |
838 | * | 848 | * |
839 | * Once we have that, we registered the bus with the kobject | 849 | * Once we have that, we registered the bus with the kobject |
840 | * infrastructure, then register the children subsystems it has: | 850 | * infrastructure, then register the children subsystems it has: |
841 | * the devices and drivers that belong to the bus. | 851 | * the devices and drivers that belong to the bus. |
842 | */ | 852 | */ |
843 | int bus_register(struct bus_type * bus) | 853 | int bus_register(struct bus_type *bus) |
844 | { | 854 | { |
845 | int retval; | 855 | int retval; |
856 | struct bus_type_private *priv; | ||
857 | |||
858 | priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); | ||
859 | if (!priv) | ||
860 | return -ENOMEM; | ||
846 | 861 | ||
847 | BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); | 862 | priv->bus = bus; |
863 | bus->p = priv; | ||
848 | 864 | ||
849 | retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name); | 865 | BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); |
866 | |||
867 | retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); | ||
850 | if (retval) | 868 | if (retval) |
851 | goto out; | 869 | goto out; |
852 | 870 | ||
853 | bus->subsys.kobj.kset = &bus_subsys; | 871 | priv->subsys.kobj.kset = bus_kset; |
872 | priv->subsys.kobj.ktype = &bus_ktype; | ||
873 | priv->drivers_autoprobe = 1; | ||
854 | 874 | ||
855 | retval = subsystem_register(&bus->subsys); | 875 | retval = kset_register(&priv->subsys); |
856 | if (retval) | 876 | if (retval) |
857 | goto out; | 877 | goto out; |
858 | 878 | ||
@@ -860,23 +880,23 @@ int bus_register(struct bus_type * bus) | |||
860 | if (retval) | 880 | if (retval) |
861 | goto bus_uevent_fail; | 881 | goto bus_uevent_fail; |
862 | 882 | ||
863 | kobject_set_name(&bus->devices.kobj, "devices"); | 883 | priv->devices_kset = kset_create_and_add("devices", NULL, |
864 | bus->devices.kobj.parent = &bus->subsys.kobj; | 884 | &priv->subsys.kobj); |
865 | retval = kset_register(&bus->devices); | 885 | if (!priv->devices_kset) { |
866 | if (retval) | 886 | retval = -ENOMEM; |
867 | goto bus_devices_fail; | 887 | goto bus_devices_fail; |
888 | } | ||
868 | 889 | ||
869 | kobject_set_name(&bus->drivers.kobj, "drivers"); | 890 | priv->drivers_kset = kset_create_and_add("drivers", NULL, |
870 | bus->drivers.kobj.parent = &bus->subsys.kobj; | 891 | &priv->subsys.kobj); |
871 | bus->drivers.ktype = &driver_ktype; | 892 | if (!priv->drivers_kset) { |
872 | retval = kset_register(&bus->drivers); | 893 | retval = -ENOMEM; |
873 | if (retval) | ||
874 | goto bus_drivers_fail; | 894 | goto bus_drivers_fail; |
895 | } | ||
875 | 896 | ||
876 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 897 | klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); |
877 | klist_init(&bus->klist_drivers, NULL, NULL); | 898 | klist_init(&priv->klist_drivers, NULL, NULL); |
878 | 899 | ||
879 | bus->drivers_autoprobe = 1; | ||
880 | retval = add_probe_files(bus); | 900 | retval = add_probe_files(bus); |
881 | if (retval) | 901 | if (retval) |
882 | goto bus_probe_files_fail; | 902 | goto bus_probe_files_fail; |
@@ -885,66 +905,73 @@ int bus_register(struct bus_type * bus) | |||
885 | if (retval) | 905 | if (retval) |
886 | goto bus_attrs_fail; | 906 | goto bus_attrs_fail; |
887 | 907 | ||
888 | pr_debug("bus type '%s' registered\n", bus->name); | 908 | pr_debug("bus: '%s': registered\n", bus->name); |
889 | return 0; | 909 | return 0; |
890 | 910 | ||
891 | bus_attrs_fail: | 911 | bus_attrs_fail: |
892 | remove_probe_files(bus); | 912 | remove_probe_files(bus); |
893 | bus_probe_files_fail: | 913 | bus_probe_files_fail: |
894 | kset_unregister(&bus->drivers); | 914 | kset_unregister(bus->p->drivers_kset); |
895 | bus_drivers_fail: | 915 | bus_drivers_fail: |
896 | kset_unregister(&bus->devices); | 916 | kset_unregister(bus->p->devices_kset); |
897 | bus_devices_fail: | 917 | bus_devices_fail: |
898 | bus_remove_file(bus, &bus_attr_uevent); | 918 | bus_remove_file(bus, &bus_attr_uevent); |
899 | bus_uevent_fail: | 919 | bus_uevent_fail: |
900 | subsystem_unregister(&bus->subsys); | 920 | kset_unregister(&bus->p->subsys); |
921 | kfree(bus->p); | ||
901 | out: | 922 | out: |
902 | return retval; | 923 | return retval; |
903 | } | 924 | } |
925 | EXPORT_SYMBOL_GPL(bus_register); | ||
904 | 926 | ||
905 | /** | 927 | /** |
906 | * bus_unregister - remove a bus from the system | 928 | * bus_unregister - remove a bus from the system |
907 | * @bus: bus. | 929 | * @bus: bus. |
908 | * | 930 | * |
909 | * Unregister the child subsystems and the bus itself. | 931 | * Unregister the child subsystems and the bus itself. |
910 | * Finally, we call bus_put() to release the refcount | 932 | * Finally, we call bus_put() to release the refcount |
911 | */ | 933 | */ |
912 | void bus_unregister(struct bus_type * bus) | 934 | void bus_unregister(struct bus_type *bus) |
913 | { | 935 | { |
914 | pr_debug("bus %s: unregistering\n", bus->name); | 936 | pr_debug("bus: '%s': unregistering\n", bus->name); |
915 | bus_remove_attrs(bus); | 937 | bus_remove_attrs(bus); |
916 | remove_probe_files(bus); | 938 | remove_probe_files(bus); |
917 | kset_unregister(&bus->drivers); | 939 | kset_unregister(bus->p->drivers_kset); |
918 | kset_unregister(&bus->devices); | 940 | kset_unregister(bus->p->devices_kset); |
919 | bus_remove_file(bus, &bus_attr_uevent); | 941 | bus_remove_file(bus, &bus_attr_uevent); |
920 | subsystem_unregister(&bus->subsys); | 942 | kset_unregister(&bus->p->subsys); |
943 | kfree(bus->p); | ||
921 | } | 944 | } |
945 | EXPORT_SYMBOL_GPL(bus_unregister); | ||
922 | 946 | ||
923 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) | 947 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) |
924 | { | 948 | { |
925 | return blocking_notifier_chain_register(&bus->bus_notifier, nb); | 949 | return blocking_notifier_chain_register(&bus->p->bus_notifier, nb); |
926 | } | 950 | } |
927 | EXPORT_SYMBOL_GPL(bus_register_notifier); | 951 | EXPORT_SYMBOL_GPL(bus_register_notifier); |
928 | 952 | ||
929 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) | 953 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) |
930 | { | 954 | { |
931 | return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); | 955 | return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb); |
932 | } | 956 | } |
933 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); | 957 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); |
934 | 958 | ||
935 | int __init buses_init(void) | 959 | struct kset *bus_get_kset(struct bus_type *bus) |
936 | { | 960 | { |
937 | return subsystem_register(&bus_subsys); | 961 | return &bus->p->subsys; |
938 | } | 962 | } |
963 | EXPORT_SYMBOL_GPL(bus_get_kset); | ||
939 | 964 | ||
965 | struct klist *bus_get_device_klist(struct bus_type *bus) | ||
966 | { | ||
967 | return &bus->p->klist_devices; | ||
968 | } | ||
969 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | ||
940 | 970 | ||
941 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | 971 | int __init buses_init(void) |
942 | EXPORT_SYMBOL_GPL(bus_find_device); | 972 | { |
943 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | 973 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); |
944 | 974 | if (!bus_kset) | |
945 | EXPORT_SYMBOL_GPL(bus_register); | 975 | return -ENOMEM; |
946 | EXPORT_SYMBOL_GPL(bus_unregister); | 976 | return 0; |
947 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | 977 | } |
948 | |||
949 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
950 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||