Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Dmitry Torokhov and committed by
Greg Kroah-Hartman
76d1ce00 d65da6ea

+32 -3
+31 -2
drivers/base/class.c
··· 452 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 473 int class_device_add(struct class_device *class_dev) 456 474 { 457 475 struct class * parent = NULL; 458 476 struct class_interface * class_intf; 477 + char *class_name = NULL; 459 478 int error; 460 479 461 480 class_dev = class_device_get(class_dev); ··· 519 500 } 520 501 521 502 class_device_add_attrs(class_dev); 522 - if (class_dev->dev) 503 + if (class_dev->dev) { 504 + class_name = make_class_name(class_dev); 523 505 sysfs_create_link(&class_dev->kobj, 524 506 &class_dev->dev->kobj, "device"); 507 + sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 508 + class_name); 509 + } 525 510 526 511 /* notify any interfaces this device is now here */ 527 512 if (parent) { ··· 542 519 if (error && parent) 543 520 class_put(parent); 544 521 class_device_put(class_dev); 522 + kfree(class_name); 545 523 return error; 546 524 } 547 525 ··· 608 584 { 609 585 struct class * parent = class_dev->class; 610 586 struct class_interface * class_intf; 587 + char *class_name = NULL; 611 588 612 589 if (parent) { 613 590 down(&parent->sem); ··· 619 594 up(&parent->sem); 620 595 } 621 596 622 - if (class_dev->dev) 597 + if (class_dev->dev) { 598 + class_name = make_class_name(class_dev); 623 599 sysfs_remove_link(&class_dev->kobj, "device"); 600 + sysfs_remove_link(&class_dev->dev->kobj, class_name); 601 + } 624 602 if (class_dev->devt_attr) 625 603 class_device_remove_file(class_dev, class_dev->devt_attr); 626 604 class_device_remove_attrs(class_dev); ··· 633 605 634 606 if (parent) 635 607 class_put(parent); 608 + kfree(class_name); 636 609 } 637 610 638 611 void class_device_unregister(struct class_device *class_dev)
+1 -1
drivers/usb/core/hcd.c
··· 782 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 786 if (IS_ERR(bus->class_dev)) { 787 787 clear_bit(busnum, busmap.busmap); 788 788 up(&usb_bus_list_lock);