diff options
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r-- | drivers/base/bus.c | 139 |
1 files changed, 82 insertions, 57 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 050d86d0b872..12173d16bea7 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/device.h> | 11 | #include <linux/device.h> |
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
14 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
@@ -130,7 +129,7 @@ static struct kobj_type ktype_bus = { | |||
130 | 129 | ||
131 | }; | 130 | }; |
132 | 131 | ||
133 | decl_subsys(bus, &ktype_bus, NULL); | 132 | static decl_subsys(bus, &ktype_bus, NULL); |
134 | 133 | ||
135 | 134 | ||
136 | #ifdef CONFIG_HOTPLUG | 135 | #ifdef CONFIG_HOTPLUG |
@@ -372,12 +371,20 @@ int bus_add_device(struct device * dev) | |||
372 | if (bus) { | 371 | if (bus) { |
373 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 372 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); |
374 | error = device_add_attrs(bus, dev); | 373 | error = device_add_attrs(bus, dev); |
375 | if (!error) { | 374 | if (error) |
376 | sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); | 375 | goto out; |
377 | sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); | 376 | error = sysfs_create_link(&bus->devices.kobj, |
378 | sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); | 377 | &dev->kobj, dev->bus_id); |
379 | } | 378 | if (error) |
379 | goto out; | ||
380 | error = sysfs_create_link(&dev->kobj, | ||
381 | &dev->bus->subsys.kset.kobj, "subsystem"); | ||
382 | if (error) | ||
383 | goto out; | ||
384 | error = sysfs_create_link(&dev->kobj, | ||
385 | &dev->bus->subsys.kset.kobj, "bus"); | ||
380 | } | 386 | } |
387 | out: | ||
381 | return error; | 388 | return error; |
382 | } | 389 | } |
383 | 390 | ||
@@ -385,16 +392,24 @@ int bus_add_device(struct device * dev) | |||
385 | * bus_attach_device - add device to bus | 392 | * bus_attach_device - add device to bus |
386 | * @dev: device tried to attach to a driver | 393 | * @dev: device tried to attach to a driver |
387 | * | 394 | * |
395 | * - Add device to bus's list of devices. | ||
388 | * - Try to attach to driver. | 396 | * - Try to attach to driver. |
389 | */ | 397 | */ |
390 | void bus_attach_device(struct device * dev) | 398 | int bus_attach_device(struct device * dev) |
391 | { | 399 | { |
392 | struct bus_type * bus = dev->bus; | 400 | struct bus_type *bus = dev->bus; |
401 | int ret = 0; | ||
393 | 402 | ||
394 | if (bus) { | 403 | if (bus) { |
395 | device_attach(dev); | 404 | dev->is_registered = 1; |
396 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); | 405 | ret = device_attach(dev); |
406 | if (ret >= 0) { | ||
407 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); | ||
408 | ret = 0; | ||
409 | } else | ||
410 | dev->is_registered = 0; | ||
397 | } | 411 | } |
412 | return ret; | ||
398 | } | 413 | } |
399 | 414 | ||
400 | /** | 415 | /** |
@@ -413,7 +428,8 @@ void bus_remove_device(struct device * dev) | |||
413 | sysfs_remove_link(&dev->kobj, "bus"); | 428 | sysfs_remove_link(&dev->kobj, "bus"); |
414 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 429 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); |
415 | device_remove_attrs(dev->bus, dev); | 430 | device_remove_attrs(dev->bus, dev); |
416 | klist_remove(&dev->knode_bus); | 431 | dev->is_registered = 0; |
432 | klist_del(&dev->knode_bus); | ||
417 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 433 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); |
418 | device_release_driver(dev); | 434 | device_release_driver(dev); |
419 | put_bus(dev->bus); | 435 | put_bus(dev->bus); |
@@ -456,10 +472,17 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr | |||
456 | * Thanks to drivers making their tables __devinit, we can't allow manual | 472 | * Thanks to drivers making their tables __devinit, we can't allow manual |
457 | * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled. | 473 | * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled. |
458 | */ | 474 | */ |
459 | static void add_bind_files(struct device_driver *drv) | 475 | static int __must_check add_bind_files(struct device_driver *drv) |
460 | { | 476 | { |
461 | driver_create_file(drv, &driver_attr_unbind); | 477 | int ret; |
462 | driver_create_file(drv, &driver_attr_bind); | 478 | |
479 | ret = driver_create_file(drv, &driver_attr_unbind); | ||
480 | if (ret == 0) { | ||
481 | ret = driver_create_file(drv, &driver_attr_bind); | ||
482 | if (ret) | ||
483 | driver_remove_file(drv, &driver_attr_unbind); | ||
484 | } | ||
485 | return ret; | ||
463 | } | 486 | } |
464 | 487 | ||
465 | static void remove_bind_files(struct device_driver *drv) | 488 | static void remove_bind_files(struct device_driver *drv) |
@@ -468,7 +491,7 @@ static void remove_bind_files(struct device_driver *drv) | |||
468 | driver_remove_file(drv, &driver_attr_unbind); | 491 | driver_remove_file(drv, &driver_attr_unbind); |
469 | } | 492 | } |
470 | #else | 493 | #else |
471 | static inline void add_bind_files(struct device_driver *drv) {} | 494 | static inline int add_bind_files(struct device_driver *drv) { return 0; } |
472 | static inline void remove_bind_files(struct device_driver *drv) {} | 495 | static inline void remove_bind_files(struct device_driver *drv) {} |
473 | #endif | 496 | #endif |
474 | 497 | ||
@@ -477,7 +500,7 @@ static inline void remove_bind_files(struct device_driver *drv) {} | |||
477 | * @drv: driver. | 500 | * @drv: driver. |
478 | * | 501 | * |
479 | */ | 502 | */ |
480 | int bus_add_driver(struct device_driver * drv) | 503 | int bus_add_driver(struct device_driver *drv) |
481 | { | 504 | { |
482 | struct bus_type * bus = get_bus(drv->bus); | 505 | struct bus_type * bus = get_bus(drv->bus); |
483 | int error = 0; | 506 | int error = 0; |
@@ -485,27 +508,39 @@ int bus_add_driver(struct device_driver * drv) | |||
485 | if (bus) { | 508 | if (bus) { |
486 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 509 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); |
487 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 510 | error = kobject_set_name(&drv->kobj, "%s", drv->name); |
488 | if (error) { | 511 | if (error) |
489 | put_bus(bus); | 512 | goto out_put_bus; |
490 | return error; | ||
491 | } | ||
492 | drv->kobj.kset = &bus->drivers; | 513 | drv->kobj.kset = &bus->drivers; |
493 | if ((error = kobject_register(&drv->kobj))) { | 514 | if ((error = kobject_register(&drv->kobj))) |
494 | put_bus(bus); | 515 | goto out_put_bus; |
495 | return error; | ||
496 | } | ||
497 | 516 | ||
498 | driver_attach(drv); | 517 | error = driver_attach(drv); |
518 | if (error) | ||
519 | goto out_unregister; | ||
499 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 520 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); |
500 | module_add_driver(drv->owner, drv); | 521 | module_add_driver(drv->owner, drv); |
501 | 522 | ||
502 | driver_add_attrs(bus, drv); | 523 | error = driver_add_attrs(bus, drv); |
503 | add_bind_files(drv); | 524 | if (error) { |
525 | /* How the hell do we get out of this pickle? Give up */ | ||
526 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | ||
527 | __FUNCTION__, drv->name); | ||
528 | } | ||
529 | error = add_bind_files(drv); | ||
530 | if (error) { | ||
531 | /* Ditto */ | ||
532 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
533 | __FUNCTION__, drv->name); | ||
534 | } | ||
504 | } | 535 | } |
505 | return error; | 536 | return error; |
537 | out_unregister: | ||
538 | kobject_unregister(&drv->kobj); | ||
539 | out_put_bus: | ||
540 | put_bus(bus); | ||
541 | return error; | ||
506 | } | 542 | } |
507 | 543 | ||
508 | |||
509 | /** | 544 | /** |
510 | * bus_remove_driver - delete driver from bus's knowledge. | 545 | * bus_remove_driver - delete driver from bus's knowledge. |
511 | * @drv: driver. | 546 | * @drv: driver. |
@@ -531,16 +566,21 @@ void bus_remove_driver(struct device_driver * drv) | |||
531 | 566 | ||
532 | 567 | ||
533 | /* Helper for bus_rescan_devices's iter */ | 568 | /* Helper for bus_rescan_devices's iter */ |
534 | static int bus_rescan_devices_helper(struct device *dev, void *data) | 569 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
570 | void *data) | ||
535 | { | 571 | { |
572 | int ret = 0; | ||
573 | |||
536 | if (!dev->driver) { | 574 | if (!dev->driver) { |
537 | if (dev->parent) /* Needed for USB */ | 575 | if (dev->parent) /* Needed for USB */ |
538 | down(&dev->parent->sem); | 576 | down(&dev->parent->sem); |
539 | device_attach(dev); | 577 | ret = device_attach(dev); |
540 | if (dev->parent) | 578 | if (dev->parent) |
541 | up(&dev->parent->sem); | 579 | up(&dev->parent->sem); |
580 | if (ret > 0) | ||
581 | ret = 0; | ||
542 | } | 582 | } |
543 | return 0; | 583 | return ret < 0 ? ret : 0; |
544 | } | 584 | } |
545 | 585 | ||
546 | /** | 586 | /** |
@@ -551,9 +591,9 @@ static int bus_rescan_devices_helper(struct device *dev, void *data) | |||
551 | * attached and rescan it against existing drivers to see if it matches | 591 | * attached and rescan it against existing drivers to see if it matches |
552 | * any by calling device_attach() for the unbound devices. | 592 | * any by calling device_attach() for the unbound devices. |
553 | */ | 593 | */ |
554 | void bus_rescan_devices(struct bus_type * bus) | 594 | int bus_rescan_devices(struct bus_type * bus) |
555 | { | 595 | { |
556 | bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); | 596 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
557 | } | 597 | } |
558 | 598 | ||
559 | /** | 599 | /** |
@@ -565,7 +605,7 @@ void bus_rescan_devices(struct bus_type * bus) | |||
565 | * to use if probing criteria changed during a devices lifetime and | 605 | * to use if probing criteria changed during a devices lifetime and |
566 | * driver attachment should change accordingly. | 606 | * driver attachment should change accordingly. |
567 | */ | 607 | */ |
568 | void device_reprobe(struct device *dev) | 608 | int device_reprobe(struct device *dev) |
569 | { | 609 | { |
570 | if (dev->driver) { | 610 | if (dev->driver) { |
571 | if (dev->parent) /* Needed for USB */ | 611 | if (dev->parent) /* Needed for USB */ |
@@ -574,14 +614,14 @@ void device_reprobe(struct device *dev) | |||
574 | if (dev->parent) | 614 | if (dev->parent) |
575 | up(&dev->parent->sem); | 615 | up(&dev->parent->sem); |
576 | } | 616 | } |
577 | 617 | return bus_rescan_devices_helper(dev, NULL); | |
578 | bus_rescan_devices_helper(dev, NULL); | ||
579 | } | 618 | } |
580 | EXPORT_SYMBOL_GPL(device_reprobe); | 619 | EXPORT_SYMBOL_GPL(device_reprobe); |
581 | 620 | ||
582 | struct bus_type * get_bus(struct bus_type * bus) | 621 | struct bus_type *get_bus(struct bus_type *bus) |
583 | { | 622 | { |
584 | return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL; | 623 | return bus ? container_of(subsys_get(&bus->subsys), |
624 | struct bus_type, subsys) : NULL; | ||
585 | } | 625 | } |
586 | 626 | ||
587 | void put_bus(struct bus_type * bus) | 627 | void put_bus(struct bus_type * bus) |
@@ -599,12 +639,13 @@ void put_bus(struct bus_type * bus) | |||
599 | * | 639 | * |
600 | * Note that kset_find_obj increments bus' reference count. | 640 | * Note that kset_find_obj increments bus' reference count. |
601 | */ | 641 | */ |
602 | 642 | #if 0 | |
603 | struct bus_type * find_bus(char * name) | 643 | struct bus_type * find_bus(char * name) |
604 | { | 644 | { |
605 | struct kobject * k = kset_find_obj(&bus_subsys.kset, name); | 645 | struct kobject * k = kset_find_obj(&bus_subsys.kset, name); |
606 | return k ? to_bus(k) : NULL; | 646 | return k ? to_bus(k) : NULL; |
607 | } | 647 | } |
648 | #endif /* 0 */ | ||
608 | 649 | ||
609 | 650 | ||
610 | /** | 651 | /** |
@@ -655,22 +696,6 @@ static void klist_devices_put(struct klist_node *n) | |||
655 | put_device(dev); | 696 | put_device(dev); |
656 | } | 697 | } |
657 | 698 | ||
658 | static void klist_drivers_get(struct klist_node *n) | ||
659 | { | ||
660 | struct device_driver *drv = container_of(n, struct device_driver, | ||
661 | knode_bus); | ||
662 | |||
663 | get_driver(drv); | ||
664 | } | ||
665 | |||
666 | static void klist_drivers_put(struct klist_node *n) | ||
667 | { | ||
668 | struct device_driver *drv = container_of(n, struct device_driver, | ||
669 | knode_bus); | ||
670 | |||
671 | put_driver(drv); | ||
672 | } | ||
673 | |||
674 | /** | 699 | /** |
675 | * bus_register - register a bus with the system. | 700 | * bus_register - register a bus with the system. |
676 | * @bus: bus. | 701 | * @bus: bus. |
@@ -706,7 +731,7 @@ int bus_register(struct bus_type * bus) | |||
706 | goto bus_drivers_fail; | 731 | goto bus_drivers_fail; |
707 | 732 | ||
708 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 733 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); |
709 | klist_init(&bus->klist_drivers, klist_drivers_get, klist_drivers_put); | 734 | klist_init(&bus->klist_drivers, NULL, NULL); |
710 | bus_add_attrs(bus); | 735 | bus_add_attrs(bus); |
711 | 736 | ||
712 | pr_debug("bus type '%s' registered\n", bus->name); | 737 | pr_debug("bus type '%s' registered\n", bus->name); |