diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2005-07-10 02:21:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-09-05 19:03:10 -0400 |
commit | 76d1ce00bdd76c2987fbfb763cd40447413a55b3 (patch) | |
tree | 153a44b7e0821d75b6dcd829a0648c62a5bc6fb9 /drivers/base | |
parent | d65da6eae10cc77f93ead0188cde0b45f124d912 (diff) |
[PATCH] Driver core: link device and all class devices derived from it.
Driver core: link device and all class devices derived from it.
To ease the task of locating class devices derived from a certain
device create symlinks from parent device to its class devices.
Change USB host class device name from usbX to usb_hostX to avoid
conflict when creating aforementioned links.
Tweaked by Greg to have the symlink be "class_name:class_device_name" in
order to prevent duplicate links.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/class.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0154a1623b21..d207296b18dc 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -452,10 +452,29 @@ void class_device_initialize(struct class_device *class_dev) | |||
452 | INIT_LIST_HEAD(&class_dev->node); | 452 | INIT_LIST_HEAD(&class_dev->node); |
453 | } | 453 | } |
454 | 454 | ||
455 | static char *make_class_name(struct class_device *class_dev) | ||
456 | { | ||
457 | char *name; | ||
458 | int size; | ||
459 | |||
460 | size = strlen(class_dev->class->name) + | ||
461 | strlen(kobject_name(&class_dev->kobj)) + 2; | ||
462 | |||
463 | name = kmalloc(size, GFP_KERNEL); | ||
464 | if (!name) | ||
465 | return ERR_PTR(-ENOMEM); | ||
466 | |||
467 | strcpy(name, class_dev->class->name); | ||
468 | strcat(name, ":"); | ||
469 | strcat(name, kobject_name(&class_dev->kobj)); | ||
470 | return name; | ||
471 | } | ||
472 | |||
455 | int class_device_add(struct class_device *class_dev) | 473 | int class_device_add(struct class_device *class_dev) |
456 | { | 474 | { |
457 | struct class * parent = NULL; | 475 | struct class * parent = NULL; |
458 | struct class_interface * class_intf; | 476 | struct class_interface * class_intf; |
477 | char *class_name = NULL; | ||
459 | int error; | 478 | int error; |
460 | 479 | ||
461 | class_dev = class_device_get(class_dev); | 480 | class_dev = class_device_get(class_dev); |
@@ -500,9 +519,13 @@ int class_device_add(struct class_device *class_dev) | |||
500 | } | 519 | } |
501 | 520 | ||
502 | class_device_add_attrs(class_dev); | 521 | class_device_add_attrs(class_dev); |
503 | if (class_dev->dev) | 522 | if (class_dev->dev) { |
523 | class_name = make_class_name(class_dev); | ||
504 | sysfs_create_link(&class_dev->kobj, | 524 | sysfs_create_link(&class_dev->kobj, |
505 | &class_dev->dev->kobj, "device"); | 525 | &class_dev->dev->kobj, "device"); |
526 | sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, | ||
527 | class_name); | ||
528 | } | ||
506 | 529 | ||
507 | /* notify any interfaces this device is now here */ | 530 | /* notify any interfaces this device is now here */ |
508 | if (parent) { | 531 | if (parent) { |
@@ -519,6 +542,7 @@ int class_device_add(struct class_device *class_dev) | |||
519 | if (error && parent) | 542 | if (error && parent) |
520 | class_put(parent); | 543 | class_put(parent); |
521 | class_device_put(class_dev); | 544 | class_device_put(class_dev); |
545 | kfree(class_name); | ||
522 | return error; | 546 | return error; |
523 | } | 547 | } |
524 | 548 | ||
@@ -584,6 +608,7 @@ void class_device_del(struct class_device *class_dev) | |||
584 | { | 608 | { |
585 | struct class * parent = class_dev->class; | 609 | struct class * parent = class_dev->class; |
586 | struct class_interface * class_intf; | 610 | struct class_interface * class_intf; |
611 | char *class_name = NULL; | ||
587 | 612 | ||
588 | if (parent) { | 613 | if (parent) { |
589 | down(&parent->sem); | 614 | down(&parent->sem); |
@@ -594,8 +619,11 @@ void class_device_del(struct class_device *class_dev) | |||
594 | up(&parent->sem); | 619 | up(&parent->sem); |
595 | } | 620 | } |
596 | 621 | ||
597 | if (class_dev->dev) | 622 | if (class_dev->dev) { |
623 | class_name = make_class_name(class_dev); | ||
598 | sysfs_remove_link(&class_dev->kobj, "device"); | 624 | sysfs_remove_link(&class_dev->kobj, "device"); |
625 | sysfs_remove_link(&class_dev->dev->kobj, class_name); | ||
626 | } | ||
599 | if (class_dev->devt_attr) | 627 | if (class_dev->devt_attr) |
600 | class_device_remove_file(class_dev, class_dev->devt_attr); | 628 | class_device_remove_file(class_dev, class_dev->devt_attr); |
601 | class_device_remove_attrs(class_dev); | 629 | class_device_remove_attrs(class_dev); |
@@ -605,6 +633,7 @@ void class_device_del(struct class_device *class_dev) | |||
605 | 633 | ||
606 | if (parent) | 634 | if (parent) |
607 | class_put(parent); | 635 | class_put(parent); |
636 | kfree(class_name); | ||
608 | } | 637 | } |
609 | 638 | ||
610 | void class_device_unregister(struct class_device *class_dev) | 639 | void class_device_unregister(struct class_device *class_dev) |