diff options
author | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-06 03:32:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-06 03:32:12 -0400 |
commit | f65e77693aa5a1cf688fc378bc6913a56f9ff7b7 (patch) | |
tree | 5d5b6ee3e3f9da241a583bf49ab648637ac4c1a9 | |
parent | 8566cfc9fe0934f52ddedc12b083176116c13978 (diff) | |
parent | d856f1e337782326c638c70c0b4df2b909350dec (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
-rw-r--r-- | Documentation/filesystems/sysfs.txt | 28 | ||||
-rw-r--r-- | drivers/base/bus.c | 8 | ||||
-rw-r--r-- | drivers/base/class.c | 39 | ||||
-rw-r--r-- | drivers/base/core.c | 2 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 | ||||
-rw-r--r-- | drivers/base/sys.c | 110 | ||||
-rw-r--r-- | drivers/block/floppy.c | 41 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 2 | ||||
-rw-r--r-- | include/linux/klist.h | 8 | ||||
-rw-r--r-- | lib/klist.c | 8 |
10 files changed, 178 insertions, 70 deletions
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index dc276598a65a..c8bce82ddcac 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt | |||
@@ -90,7 +90,7 @@ void device_remove_file(struct device *, struct device_attribute *); | |||
90 | 90 | ||
91 | It also defines this helper for defining device attributes: | 91 | It also defines this helper for defining device attributes: |
92 | 92 | ||
93 | #define DEVICE_ATTR(_name,_mode,_show,_store) \ | 93 | #define DEVICE_ATTR(_name, _mode, _show, _store) \ |
94 | struct device_attribute dev_attr_##_name = { \ | 94 | struct device_attribute dev_attr_##_name = { \ |
95 | .attr = {.name = __stringify(_name) , .mode = _mode }, \ | 95 | .attr = {.name = __stringify(_name) , .mode = _mode }, \ |
96 | .show = _show, \ | 96 | .show = _show, \ |
@@ -99,14 +99,14 @@ struct device_attribute dev_attr_##_name = { \ | |||
99 | 99 | ||
100 | For example, declaring | 100 | For example, declaring |
101 | 101 | ||
102 | static DEVICE_ATTR(foo,0644,show_foo,store_foo); | 102 | static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo); |
103 | 103 | ||
104 | is equivalent to doing: | 104 | is equivalent to doing: |
105 | 105 | ||
106 | static struct device_attribute dev_attr_foo = { | 106 | static struct device_attribute dev_attr_foo = { |
107 | .attr = { | 107 | .attr = { |
108 | .name = "foo", | 108 | .name = "foo", |
109 | .mode = 0644, | 109 | .mode = S_IWUSR | S_IRUGO, |
110 | }, | 110 | }, |
111 | .show = show_foo, | 111 | .show = show_foo, |
112 | .store = store_foo, | 112 | .store = store_foo, |
@@ -121,8 +121,8 @@ set of sysfs operations for forwarding read and write calls to the | |||
121 | show and store methods of the attribute owners. | 121 | show and store methods of the attribute owners. |
122 | 122 | ||
123 | struct sysfs_ops { | 123 | struct sysfs_ops { |
124 | ssize_t (*show)(struct kobject *, struct attribute *,char *); | 124 | ssize_t (*show)(struct kobject *, struct attribute *, char *); |
125 | ssize_t (*store)(struct kobject *,struct attribute *,const char *); | 125 | ssize_t (*store)(struct kobject *, struct attribute *, const char *); |
126 | }; | 126 | }; |
127 | 127 | ||
128 | [ Subsystems should have already defined a struct kobj_type as a | 128 | [ Subsystems should have already defined a struct kobj_type as a |
@@ -137,7 +137,7 @@ calls the associated methods. | |||
137 | 137 | ||
138 | To illustrate: | 138 | To illustrate: |
139 | 139 | ||
140 | #define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr) | 140 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
141 | #define to_dev(d) container_of(d, struct device, kobj) | 141 | #define to_dev(d) container_of(d, struct device, kobj) |
142 | 142 | ||
143 | static ssize_t | 143 | static ssize_t |
@@ -148,7 +148,7 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
148 | ssize_t ret = 0; | 148 | ssize_t ret = 0; |
149 | 149 | ||
150 | if (dev_attr->show) | 150 | if (dev_attr->show) |
151 | ret = dev_attr->show(dev,buf); | 151 | ret = dev_attr->show(dev, buf); |
152 | return ret; | 152 | return ret; |
153 | } | 153 | } |
154 | 154 | ||
@@ -216,16 +216,16 @@ A very simple (and naive) implementation of a device attribute is: | |||
216 | 216 | ||
217 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) | 217 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) |
218 | { | 218 | { |
219 | return sprintf(buf,"%s\n",dev->name); | 219 | return snprintf(buf, PAGE_SIZE, "%s\n", dev->name); |
220 | } | 220 | } |
221 | 221 | ||
222 | static ssize_t store_name(struct device * dev, const char * buf) | 222 | static ssize_t store_name(struct device * dev, const char * buf) |
223 | { | 223 | { |
224 | sscanf(buf,"%20s",dev->name); | 224 | sscanf(buf, "%20s", dev->name); |
225 | return strlen(buf); | 225 | return strnlen(buf, PAGE_SIZE); |
226 | } | 226 | } |
227 | 227 | ||
228 | static DEVICE_ATTR(name,S_IRUGO,show_name,store_name); | 228 | static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); |
229 | 229 | ||
230 | 230 | ||
231 | (Note that the real implementation doesn't allow userspace to set the | 231 | (Note that the real implementation doesn't allow userspace to set the |
@@ -290,7 +290,7 @@ struct device_attribute { | |||
290 | 290 | ||
291 | Declaring: | 291 | Declaring: |
292 | 292 | ||
293 | DEVICE_ATTR(_name,_str,_mode,_show,_store); | 293 | DEVICE_ATTR(_name, _str, _mode, _show, _store); |
294 | 294 | ||
295 | Creation/Removal: | 295 | Creation/Removal: |
296 | 296 | ||
@@ -310,7 +310,7 @@ struct bus_attribute { | |||
310 | 310 | ||
311 | Declaring: | 311 | Declaring: |
312 | 312 | ||
313 | BUS_ATTR(_name,_mode,_show,_store) | 313 | BUS_ATTR(_name, _mode, _show, _store) |
314 | 314 | ||
315 | Creation/Removal: | 315 | Creation/Removal: |
316 | 316 | ||
@@ -331,7 +331,7 @@ struct driver_attribute { | |||
331 | 331 | ||
332 | Declaring: | 332 | Declaring: |
333 | 333 | ||
334 | DRIVER_ATTR(_name,_mode,_show,_store) | 334 | DRIVER_ATTR(_name, _mode, _show, _store) |
335 | 335 | ||
336 | Creation/Removal: | 336 | Creation/Removal: |
337 | 337 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index ab53832d57e5..17e96698410e 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -156,7 +156,9 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
156 | device_release_driver(dev); | 156 | device_release_driver(dev); |
157 | err = count; | 157 | err = count; |
158 | } | 158 | } |
159 | return err; | 159 | if (err) |
160 | return err; | ||
161 | return count; | ||
160 | } | 162 | } |
161 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | 163 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); |
162 | 164 | ||
@@ -358,7 +360,7 @@ int bus_add_device(struct device * dev) | |||
358 | if (bus) { | 360 | if (bus) { |
359 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 361 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); |
360 | device_attach(dev); | 362 | device_attach(dev); |
361 | klist_add_tail(&bus->klist_devices, &dev->knode_bus); | 363 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); |
362 | error = device_add_attrs(bus, dev); | 364 | error = device_add_attrs(bus, dev); |
363 | if (!error) { | 365 | if (!error) { |
364 | sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); | 366 | sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); |
@@ -446,7 +448,7 @@ int bus_add_driver(struct device_driver * drv) | |||
446 | } | 448 | } |
447 | 449 | ||
448 | driver_attach(drv); | 450 | driver_attach(drv); |
449 | klist_add_tail(&bus->klist_drivers, &drv->knode_bus); | 451 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); |
450 | module_add_driver(drv->owner, drv); | 452 | module_add_driver(drv->owner, drv); |
451 | 453 | ||
452 | driver_add_attrs(bus, drv); | 454 | driver_add_attrs(bus, drv); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0154a1623b21..d164c32a97ad 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -299,10 +299,8 @@ static void class_dev_release(struct kobject * kobj) | |||
299 | 299 | ||
300 | pr_debug("device class '%s': release.\n", cd->class_id); | 300 | pr_debug("device class '%s': release.\n", cd->class_id); |
301 | 301 | ||
302 | if (cd->devt_attr) { | 302 | kfree(cd->devt_attr); |
303 | kfree(cd->devt_attr); | 303 | cd->devt_attr = NULL; |
304 | cd->devt_attr = NULL; | ||
305 | } | ||
306 | 304 | ||
307 | if (cls->release) | 305 | if (cls->release) |
308 | cls->release(cd); | 306 | cls->release(cd); |
@@ -452,10 +450,29 @@ void class_device_initialize(struct class_device *class_dev) | |||
452 | INIT_LIST_HEAD(&class_dev->node); | 450 | INIT_LIST_HEAD(&class_dev->node); |
453 | } | 451 | } |
454 | 452 | ||
453 | static char *make_class_name(struct class_device *class_dev) | ||
454 | { | ||
455 | char *name; | ||
456 | int size; | ||
457 | |||
458 | size = strlen(class_dev->class->name) + | ||
459 | strlen(kobject_name(&class_dev->kobj)) + 2; | ||
460 | |||
461 | name = kmalloc(size, GFP_KERNEL); | ||
462 | if (!name) | ||
463 | return ERR_PTR(-ENOMEM); | ||
464 | |||
465 | strcpy(name, class_dev->class->name); | ||
466 | strcat(name, ":"); | ||
467 | strcat(name, kobject_name(&class_dev->kobj)); | ||
468 | return name; | ||
469 | } | ||
470 | |||
455 | int class_device_add(struct class_device *class_dev) | 471 | int class_device_add(struct class_device *class_dev) |
456 | { | 472 | { |
457 | struct class * parent = NULL; | 473 | struct class * parent = NULL; |
458 | struct class_interface * class_intf; | 474 | struct class_interface * class_intf; |
475 | char *class_name = NULL; | ||
459 | int error; | 476 | int error; |
460 | 477 | ||
461 | class_dev = class_device_get(class_dev); | 478 | class_dev = class_device_get(class_dev); |
@@ -500,9 +517,13 @@ int class_device_add(struct class_device *class_dev) | |||
500 | } | 517 | } |
501 | 518 | ||
502 | class_device_add_attrs(class_dev); | 519 | class_device_add_attrs(class_dev); |
503 | if (class_dev->dev) | 520 | if (class_dev->dev) { |
521 | class_name = make_class_name(class_dev); | ||
504 | sysfs_create_link(&class_dev->kobj, | 522 | sysfs_create_link(&class_dev->kobj, |
505 | &class_dev->dev->kobj, "device"); | 523 | &class_dev->dev->kobj, "device"); |
524 | sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, | ||
525 | class_name); | ||
526 | } | ||
506 | 527 | ||
507 | /* notify any interfaces this device is now here */ | 528 | /* notify any interfaces this device is now here */ |
508 | if (parent) { | 529 | if (parent) { |
@@ -519,6 +540,7 @@ int class_device_add(struct class_device *class_dev) | |||
519 | if (error && parent) | 540 | if (error && parent) |
520 | class_put(parent); | 541 | class_put(parent); |
521 | class_device_put(class_dev); | 542 | class_device_put(class_dev); |
543 | kfree(class_name); | ||
522 | return error; | 544 | return error; |
523 | } | 545 | } |
524 | 546 | ||
@@ -584,6 +606,7 @@ void class_device_del(struct class_device *class_dev) | |||
584 | { | 606 | { |
585 | struct class * parent = class_dev->class; | 607 | struct class * parent = class_dev->class; |
586 | struct class_interface * class_intf; | 608 | struct class_interface * class_intf; |
609 | char *class_name = NULL; | ||
587 | 610 | ||
588 | if (parent) { | 611 | if (parent) { |
589 | down(&parent->sem); | 612 | down(&parent->sem); |
@@ -594,8 +617,11 @@ void class_device_del(struct class_device *class_dev) | |||
594 | up(&parent->sem); | 617 | up(&parent->sem); |
595 | } | 618 | } |
596 | 619 | ||
597 | if (class_dev->dev) | 620 | if (class_dev->dev) { |
621 | class_name = make_class_name(class_dev); | ||
598 | sysfs_remove_link(&class_dev->kobj, "device"); | 622 | sysfs_remove_link(&class_dev->kobj, "device"); |
623 | sysfs_remove_link(&class_dev->dev->kobj, class_name); | ||
624 | } | ||
599 | if (class_dev->devt_attr) | 625 | if (class_dev->devt_attr) |
600 | class_device_remove_file(class_dev, class_dev->devt_attr); | 626 | class_device_remove_file(class_dev, class_dev->devt_attr); |
601 | class_device_remove_attrs(class_dev); | 627 | class_device_remove_attrs(class_dev); |
@@ -605,6 +631,7 @@ void class_device_del(struct class_device *class_dev) | |||
605 | 631 | ||
606 | if (parent) | 632 | if (parent) |
607 | class_put(parent); | 633 | class_put(parent); |
634 | kfree(class_name); | ||
608 | } | 635 | } |
609 | 636 | ||
610 | void class_device_unregister(struct class_device *class_dev) | 637 | void class_device_unregister(struct class_device *class_dev) |
diff --git a/drivers/base/core.c b/drivers/base/core.c index efe03a024a5b..c8a33df00761 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -249,7 +249,7 @@ int device_add(struct device *dev) | |||
249 | if ((error = bus_add_device(dev))) | 249 | if ((error = bus_add_device(dev))) |
250 | goto BusError; | 250 | goto BusError; |
251 | if (parent) | 251 | if (parent) |
252 | klist_add_tail(&parent->klist_children, &dev->knode_parent); | 252 | klist_add_tail(&dev->knode_parent, &parent->klist_children); |
253 | 253 | ||
254 | /* notify platform of device entry */ | 254 | /* notify platform of device entry */ |
255 | if (platform_notify) | 255 | if (platform_notify) |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 16323f9cbff0..d5bbce38282f 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -42,7 +42,7 @@ void device_bind_driver(struct device * dev) | |||
42 | { | 42 | { |
43 | pr_debug("bound device '%s' to driver '%s'\n", | 43 | pr_debug("bound device '%s' to driver '%s'\n", |
44 | dev->bus_id, dev->driver->name); | 44 | dev->bus_id, dev->driver->name); |
45 | klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver); | 45 | klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); |
46 | sysfs_create_link(&dev->driver->kobj, &dev->kobj, | 46 | sysfs_create_link(&dev->driver->kobj, &dev->kobj, |
47 | kobject_name(&dev->kobj)); | 47 | kobject_name(&dev->kobj)); |
48 | sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); | 48 | sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 214b96435409..3431eb6004c3 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -288,6 +288,27 @@ void sysdev_shutdown(void) | |||
288 | up(&sysdev_drivers_lock); | 288 | up(&sysdev_drivers_lock); |
289 | } | 289 | } |
290 | 290 | ||
291 | static void __sysdev_resume(struct sys_device *dev) | ||
292 | { | ||
293 | struct sysdev_class *cls = dev->cls; | ||
294 | struct sysdev_driver *drv; | ||
295 | |||
296 | /* First, call the class-specific one */ | ||
297 | if (cls->resume) | ||
298 | cls->resume(dev); | ||
299 | |||
300 | /* Call auxillary drivers next. */ | ||
301 | list_for_each_entry(drv, &cls->drivers, entry) { | ||
302 | if (drv->resume) | ||
303 | drv->resume(dev); | ||
304 | } | ||
305 | |||
306 | /* Call global drivers. */ | ||
307 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
308 | if (drv->resume) | ||
309 | drv->resume(dev); | ||
310 | } | ||
311 | } | ||
291 | 312 | ||
292 | /** | 313 | /** |
293 | * sysdev_suspend - Suspend all system devices. | 314 | * sysdev_suspend - Suspend all system devices. |
@@ -305,38 +326,93 @@ void sysdev_shutdown(void) | |||
305 | int sysdev_suspend(pm_message_t state) | 326 | int sysdev_suspend(pm_message_t state) |
306 | { | 327 | { |
307 | struct sysdev_class * cls; | 328 | struct sysdev_class * cls; |
329 | struct sys_device *sysdev, *err_dev; | ||
330 | struct sysdev_driver *drv, *err_drv; | ||
331 | int ret; | ||
308 | 332 | ||
309 | pr_debug("Suspending System Devices\n"); | 333 | pr_debug("Suspending System Devices\n"); |
310 | 334 | ||
311 | list_for_each_entry_reverse(cls, &system_subsys.kset.list, | 335 | list_for_each_entry_reverse(cls, &system_subsys.kset.list, |
312 | kset.kobj.entry) { | 336 | kset.kobj.entry) { |
313 | struct sys_device * sysdev; | ||
314 | 337 | ||
315 | pr_debug("Suspending type '%s':\n", | 338 | pr_debug("Suspending type '%s':\n", |
316 | kobject_name(&cls->kset.kobj)); | 339 | kobject_name(&cls->kset.kobj)); |
317 | 340 | ||
318 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 341 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
319 | struct sysdev_driver * drv; | ||
320 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 342 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
321 | 343 | ||
322 | /* Call global drivers first. */ | 344 | /* Call global drivers first. */ |
323 | list_for_each_entry(drv, &sysdev_drivers, entry) { | 345 | list_for_each_entry(drv, &sysdev_drivers, entry) { |
324 | if (drv->suspend) | 346 | if (drv->suspend) { |
325 | drv->suspend(sysdev, state); | 347 | ret = drv->suspend(sysdev, state); |
348 | if (ret) | ||
349 | goto gbl_driver; | ||
350 | } | ||
326 | } | 351 | } |
327 | 352 | ||
328 | /* Call auxillary drivers next. */ | 353 | /* Call auxillary drivers next. */ |
329 | list_for_each_entry(drv, &cls->drivers, entry) { | 354 | list_for_each_entry(drv, &cls->drivers, entry) { |
330 | if (drv->suspend) | 355 | if (drv->suspend) { |
331 | drv->suspend(sysdev, state); | 356 | ret = drv->suspend(sysdev, state); |
357 | if (ret) | ||
358 | goto aux_driver; | ||
359 | } | ||
332 | } | 360 | } |
333 | 361 | ||
334 | /* Now call the generic one */ | 362 | /* Now call the generic one */ |
335 | if (cls->suspend) | 363 | if (cls->suspend) { |
336 | cls->suspend(sysdev, state); | 364 | ret = cls->suspend(sysdev, state); |
365 | if (ret) | ||
366 | goto cls_driver; | ||
367 | } | ||
337 | } | 368 | } |
338 | } | 369 | } |
339 | return 0; | 370 | return 0; |
371 | /* resume current sysdev */ | ||
372 | cls_driver: | ||
373 | drv = NULL; | ||
374 | printk(KERN_ERR "Class suspend failed for %s\n", | ||
375 | kobject_name(&sysdev->kobj)); | ||
376 | |||
377 | aux_driver: | ||
378 | if (drv) | ||
379 | printk(KERN_ERR "Class driver suspend failed for %s\n", | ||
380 | kobject_name(&sysdev->kobj)); | ||
381 | list_for_each_entry(err_drv, &cls->drivers, entry) { | ||
382 | if (err_drv == drv) | ||
383 | break; | ||
384 | if (err_drv->resume) | ||
385 | err_drv->resume(sysdev); | ||
386 | } | ||
387 | drv = NULL; | ||
388 | |||
389 | gbl_driver: | ||
390 | if (drv) | ||
391 | printk(KERN_ERR "sysdev driver suspend failed for %s\n", | ||
392 | kobject_name(&sysdev->kobj)); | ||
393 | list_for_each_entry(err_drv, &sysdev_drivers, entry) { | ||
394 | if (err_drv == drv) | ||
395 | break; | ||
396 | if (err_drv->resume) | ||
397 | err_drv->resume(sysdev); | ||
398 | } | ||
399 | /* resume other sysdevs in current class */ | ||
400 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { | ||
401 | if (err_dev == sysdev) | ||
402 | break; | ||
403 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); | ||
404 | __sysdev_resume(err_dev); | ||
405 | } | ||
406 | |||
407 | /* resume other classes */ | ||
408 | list_for_each_entry_continue(cls, &system_subsys.kset.list, | ||
409 | kset.kobj.entry) { | ||
410 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { | ||
411 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); | ||
412 | __sysdev_resume(err_dev); | ||
413 | } | ||
414 | } | ||
415 | return ret; | ||
340 | } | 416 | } |
341 | 417 | ||
342 | 418 | ||
@@ -362,25 +438,9 @@ int sysdev_resume(void) | |||
362 | kobject_name(&cls->kset.kobj)); | 438 | kobject_name(&cls->kset.kobj)); |
363 | 439 | ||
364 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 440 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
365 | struct sysdev_driver * drv; | ||
366 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 441 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
367 | 442 | ||
368 | /* First, call the class-specific one */ | 443 | __sysdev_resume(sysdev); |
369 | if (cls->resume) | ||
370 | cls->resume(sysdev); | ||
371 | |||
372 | /* Call auxillary drivers next. */ | ||
373 | list_for_each_entry(drv, &cls->drivers, entry) { | ||
374 | if (drv->resume) | ||
375 | drv->resume(sysdev); | ||
376 | } | ||
377 | |||
378 | /* Call global drivers. */ | ||
379 | list_for_each_entry(drv, &sysdev_drivers, entry) { | ||
380 | if (drv->resume) | ||
381 | drv->resume(sysdev); | ||
382 | } | ||
383 | |||
384 | } | 444 | } |
385 | } | 445 | } |
386 | return 0; | 446 | return 0; |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index f0c1084b840f..888dad5eef34 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -493,6 +493,8 @@ static struct floppy_struct user_params[N_DRIVE]; | |||
493 | 493 | ||
494 | static sector_t floppy_sizes[256]; | 494 | static sector_t floppy_sizes[256]; |
495 | 495 | ||
496 | static char floppy_device_name[] = "floppy"; | ||
497 | |||
496 | /* | 498 | /* |
497 | * The driver is trying to determine the correct media format | 499 | * The driver is trying to determine the correct media format |
498 | * while probing is set. rw_interrupt() clears it after a | 500 | * while probing is set. rw_interrupt() clears it after a |
@@ -4191,18 +4193,24 @@ static int __init floppy_setup(char *str) | |||
4191 | 4193 | ||
4192 | static int have_no_fdc = -ENODEV; | 4194 | static int have_no_fdc = -ENODEV; |
4193 | 4195 | ||
4196 | static ssize_t floppy_cmos_show(struct device *dev, | ||
4197 | struct device_attribute *attr, char *buf) | ||
4198 | { | ||
4199 | struct platform_device *p; | ||
4200 | int drive; | ||
4201 | |||
4202 | p = container_of(dev, struct platform_device,dev); | ||
4203 | drive = p->id; | ||
4204 | return sprintf(buf, "%X\n", UDP->cmos); | ||
4205 | } | ||
4206 | DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); | ||
4207 | |||
4194 | static void floppy_device_release(struct device *dev) | 4208 | static void floppy_device_release(struct device *dev) |
4195 | { | 4209 | { |
4196 | complete(&device_release); | 4210 | complete(&device_release); |
4197 | } | 4211 | } |
4198 | 4212 | ||
4199 | static struct platform_device floppy_device = { | 4213 | static struct platform_device floppy_device[N_DRIVE]; |
4200 | .name = "floppy", | ||
4201 | .id = 0, | ||
4202 | .dev = { | ||
4203 | .release = floppy_device_release, | ||
4204 | } | ||
4205 | }; | ||
4206 | 4214 | ||
4207 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) | 4215 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) |
4208 | { | 4216 | { |
@@ -4370,20 +4378,26 @@ static int __init floppy_init(void) | |||
4370 | goto out_flush_work; | 4378 | goto out_flush_work; |
4371 | } | 4379 | } |
4372 | 4380 | ||
4373 | err = platform_device_register(&floppy_device); | ||
4374 | if (err) | ||
4375 | goto out_flush_work; | ||
4376 | |||
4377 | for (drive = 0; drive < N_DRIVE; drive++) { | 4381 | for (drive = 0; drive < N_DRIVE; drive++) { |
4378 | if (!(allowed_drive_mask & (1 << drive))) | 4382 | if (!(allowed_drive_mask & (1 << drive))) |
4379 | continue; | 4383 | continue; |
4380 | if (fdc_state[FDC(drive)].version == FDC_NONE) | 4384 | if (fdc_state[FDC(drive)].version == FDC_NONE) |
4381 | continue; | 4385 | continue; |
4386 | |||
4387 | floppy_device[drive].name = floppy_device_name; | ||
4388 | floppy_device[drive].id = drive; | ||
4389 | floppy_device[drive].dev.release = floppy_device_release; | ||
4390 | |||
4391 | err = platform_device_register(&floppy_device[drive]); | ||
4392 | if (err) | ||
4393 | goto out_flush_work; | ||
4394 | |||
4395 | device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); | ||
4382 | /* to be cleaned up... */ | 4396 | /* to be cleaned up... */ |
4383 | disks[drive]->private_data = (void *)(long)drive; | 4397 | disks[drive]->private_data = (void *)(long)drive; |
4384 | disks[drive]->queue = floppy_queue; | 4398 | disks[drive]->queue = floppy_queue; |
4385 | disks[drive]->flags |= GENHD_FL_REMOVABLE; | 4399 | disks[drive]->flags |= GENHD_FL_REMOVABLE; |
4386 | disks[drive]->driverfs_dev = &floppy_device.dev; | 4400 | disks[drive]->driverfs_dev = &floppy_device[drive].dev; |
4387 | add_disk(disks[drive]); | 4401 | add_disk(disks[drive]); |
4388 | } | 4402 | } |
4389 | 4403 | ||
@@ -4603,10 +4617,11 @@ void cleanup_module(void) | |||
4603 | fdc_state[FDC(drive)].version != FDC_NONE) { | 4617 | fdc_state[FDC(drive)].version != FDC_NONE) { |
4604 | del_gendisk(disks[drive]); | 4618 | del_gendisk(disks[drive]); |
4605 | unregister_devfs_entries(drive); | 4619 | unregister_devfs_entries(drive); |
4620 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | ||
4621 | platform_device_unregister(&floppy_device[drive]); | ||
4606 | } | 4622 | } |
4607 | put_disk(disks[drive]); | 4623 | put_disk(disks[drive]); |
4608 | } | 4624 | } |
4609 | platform_device_unregister(&floppy_device); | ||
4610 | devfs_remove("floppy"); | 4625 | devfs_remove("floppy"); |
4611 | 4626 | ||
4612 | del_timer_sync(&fd_timeout); | 4627 | del_timer_sync(&fd_timeout); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 79422a3b07bc..9f44e83c6a69 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -782,7 +782,7 @@ static int usb_register_bus(struct usb_bus *bus) | |||
782 | return -E2BIG; | 782 | return -E2BIG; |
783 | } | 783 | } |
784 | 784 | ||
785 | bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum); | 785 | bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum); |
786 | if (IS_ERR(bus->class_dev)) { | 786 | if (IS_ERR(bus->class_dev)) { |
787 | clear_bit(busnum, busmap.busmap); | 787 | clear_bit(busnum, busmap.busmap); |
788 | up(&usb_bus_list_lock); | 788 | up(&usb_bus_list_lock); |
diff --git a/include/linux/klist.h b/include/linux/klist.h index eebf5e5696ec..c4d1fae4dd89 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h | |||
@@ -9,6 +9,9 @@ | |||
9 | * This file is rleased under the GPL v2. | 9 | * This file is rleased under the GPL v2. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef _LINUX_KLIST_H | ||
13 | #define _LINUX_KLIST_H | ||
14 | |||
12 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 16 | #include <linux/completion.h> |
14 | #include <linux/kref.h> | 17 | #include <linux/kref.h> |
@@ -31,8 +34,8 @@ struct klist_node { | |||
31 | struct completion n_removed; | 34 | struct completion n_removed; |
32 | }; | 35 | }; |
33 | 36 | ||
34 | extern void klist_add_tail(struct klist * k, struct klist_node * n); | 37 | extern void klist_add_tail(struct klist_node * n, struct klist * k); |
35 | extern void klist_add_head(struct klist * k, struct klist_node * n); | 38 | extern void klist_add_head(struct klist_node * n, struct klist * k); |
36 | 39 | ||
37 | extern void klist_del(struct klist_node * n); | 40 | extern void klist_del(struct klist_node * n); |
38 | extern void klist_remove(struct klist_node * n); | 41 | extern void klist_remove(struct klist_node * n); |
@@ -53,3 +56,4 @@ extern void klist_iter_init_node(struct klist * k, struct klist_iter * i, | |||
53 | extern void klist_iter_exit(struct klist_iter * i); | 56 | extern void klist_iter_exit(struct klist_iter * i); |
54 | extern struct klist_node * klist_next(struct klist_iter * i); | 57 | extern struct klist_node * klist_next(struct klist_iter * i); |
55 | 58 | ||
59 | #endif | ||
diff --git a/lib/klist.c b/lib/klist.c index 738ab810160a..a70c836c5c4c 100644 --- a/lib/klist.c +++ b/lib/klist.c | |||
@@ -79,11 +79,11 @@ static void klist_node_init(struct klist * k, struct klist_node * n) | |||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * klist_add_head - Initialize a klist_node and add it to front. | 81 | * klist_add_head - Initialize a klist_node and add it to front. |
82 | * @k: klist it's going on. | ||
83 | * @n: node we're adding. | 82 | * @n: node we're adding. |
83 | * @k: klist it's going on. | ||
84 | */ | 84 | */ |
85 | 85 | ||
86 | void klist_add_head(struct klist * k, struct klist_node * n) | 86 | void klist_add_head(struct klist_node * n, struct klist * k) |
87 | { | 87 | { |
88 | klist_node_init(k, n); | 88 | klist_node_init(k, n); |
89 | add_head(k, n); | 89 | add_head(k, n); |
@@ -94,11 +94,11 @@ EXPORT_SYMBOL_GPL(klist_add_head); | |||
94 | 94 | ||
95 | /** | 95 | /** |
96 | * klist_add_tail - Initialize a klist_node and add it to back. | 96 | * klist_add_tail - Initialize a klist_node and add it to back. |
97 | * @k: klist it's going on. | ||
98 | * @n: node we're adding. | 97 | * @n: node we're adding. |
98 | * @k: klist it's going on. | ||
99 | */ | 99 | */ |
100 | 100 | ||
101 | void klist_add_tail(struct klist * k, struct klist_node * n) | 101 | void klist_add_tail(struct klist_node * n, struct klist * k) |
102 | { | 102 | { |
103 | klist_node_init(k, n); | 103 | klist_node_init(k, n); |
104 | add_tail(k, n); | 104 | add_tail(k, n); |