diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2009-06-15 22:01:25 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-06-16 17:30:11 -0400 |
commit | c825bc94c8c1908750ab20413eb639c6be029e2d (patch) | |
tree | 6e5800fe52e0f94f42fdcd4c327b8cfaf803978a /drivers/pci | |
parent | 498a8faf2c7eb974f70b7c5a60a31f0d48c35d44 (diff) |
PCI hotplug: create symlink to hotplug driver module
Create symbolic link to hotplug driver module in the PCI slot
directory (/sys/bus/pci/slots/<SLOT#>). In the past, we need to load
hotplug drivers one by one to identify the hotplug driver that handles
the slot, and it was very inconvenient especially for trouble shooting.
With this change, we can easily identify the hotplug driver.
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Reviewed-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 23 | ||||
-rw-r--r-- | drivers/pci/slot.c | 39 |
2 files changed, 55 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index ff32c6b4ae13..844580489d4d 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -424,6 +424,9 @@ static int fs_add_slot(struct pci_slot *slot) | |||
424 | { | 424 | { |
425 | int retval = 0; | 425 | int retval = 0; |
426 | 426 | ||
427 | /* Create symbolic link to the hotplug driver module */ | ||
428 | pci_hp_create_module_link(slot); | ||
429 | |||
427 | if (has_power_file(slot)) { | 430 | if (has_power_file(slot)) { |
428 | retval = sysfs_create_file(&slot->kobj, | 431 | retval = sysfs_create_file(&slot->kobj, |
429 | &hotplug_slot_attr_power.attr); | 432 | &hotplug_slot_attr_power.attr); |
@@ -498,6 +501,7 @@ exit_attention: | |||
498 | if (has_power_file(slot)) | 501 | if (has_power_file(slot)) |
499 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); | 502 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); |
500 | exit_power: | 503 | exit_power: |
504 | pci_hp_remove_module_link(slot); | ||
501 | exit: | 505 | exit: |
502 | return retval; | 506 | return retval; |
503 | } | 507 | } |
@@ -528,6 +532,8 @@ static void fs_remove_slot(struct pci_slot *slot) | |||
528 | 532 | ||
529 | if (has_test_file(slot)) | 533 | if (has_test_file(slot)) |
530 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 534 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); |
535 | |||
536 | pci_hp_remove_module_link(slot); | ||
531 | } | 537 | } |
532 | 538 | ||
533 | static struct hotplug_slot *get_slot_from_name (const char *name) | 539 | static struct hotplug_slot *get_slot_from_name (const char *name) |
@@ -544,10 +550,10 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
544 | } | 550 | } |
545 | 551 | ||
546 | /** | 552 | /** |
547 | * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem | 553 | * __pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem |
548 | * @bus: bus this slot is on | 554 | * @bus: bus this slot is on |
549 | * @slot: pointer to the &struct hotplug_slot to register | 555 | * @slot: pointer to the &struct hotplug_slot to register |
550 | * @slot_nr: slot number | 556 | * @devnr: device number |
551 | * @name: name registered with kobject core | 557 | * @name: name registered with kobject core |
552 | * | 558 | * |
553 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow | 559 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow |
@@ -555,8 +561,9 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
555 | * | 561 | * |
556 | * Returns 0 if successful, anything else for an error. | 562 | * Returns 0 if successful, anything else for an error. |
557 | */ | 563 | */ |
558 | int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr, | 564 | int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, |
559 | const char *name) | 565 | int devnr, const char *name, |
566 | struct module *owner, const char *mod_name) | ||
560 | { | 567 | { |
561 | int result; | 568 | int result; |
562 | struct pci_slot *pci_slot; | 569 | struct pci_slot *pci_slot; |
@@ -571,14 +578,16 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr, | |||
571 | return -EINVAL; | 578 | return -EINVAL; |
572 | } | 579 | } |
573 | 580 | ||
574 | mutex_lock(&pci_hp_mutex); | 581 | slot->ops->owner = owner; |
582 | slot->ops->mod_name = mod_name; | ||
575 | 583 | ||
584 | mutex_lock(&pci_hp_mutex); | ||
576 | /* | 585 | /* |
577 | * No problems if we call this interface from both ACPI_PCI_SLOT | 586 | * No problems if we call this interface from both ACPI_PCI_SLOT |
578 | * driver and call it here again. If we've already created the | 587 | * driver and call it here again. If we've already created the |
579 | * pci_slot, the interface will simply bump the refcount. | 588 | * pci_slot, the interface will simply bump the refcount. |
580 | */ | 589 | */ |
581 | pci_slot = pci_create_slot(bus, slot_nr, name, slot); | 590 | pci_slot = pci_create_slot(bus, devnr, name, slot); |
582 | if (IS_ERR(pci_slot)) { | 591 | if (IS_ERR(pci_slot)) { |
583 | result = PTR_ERR(pci_slot); | 592 | result = PTR_ERR(pci_slot); |
584 | goto out; | 593 | goto out; |
@@ -688,6 +697,6 @@ MODULE_LICENSE("GPL"); | |||
688 | module_param(debug, bool, 0644); | 697 | module_param(debug, bool, 0644); |
689 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 698 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
690 | 699 | ||
691 | EXPORT_SYMBOL_GPL(pci_hp_register); | 700 | EXPORT_SYMBOL_GPL(__pci_hp_register); |
692 | EXPORT_SYMBOL_GPL(pci_hp_deregister); | 701 | EXPORT_SYMBOL_GPL(pci_hp_deregister); |
693 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); | 702 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index fe95ce20bcbd..eddb0748b0ea 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -307,6 +307,45 @@ void pci_destroy_slot(struct pci_slot *slot) | |||
307 | } | 307 | } |
308 | EXPORT_SYMBOL_GPL(pci_destroy_slot); | 308 | EXPORT_SYMBOL_GPL(pci_destroy_slot); |
309 | 309 | ||
310 | #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) | ||
311 | #include <linux/pci_hotplug.h> | ||
312 | /** | ||
313 | * pci_hp_create_link - create symbolic link to the hotplug driver module. | ||
314 | * @slot: struct pci_slot | ||
315 | * | ||
316 | * Helper function for pci_hotplug_core.c to create symbolic link to | ||
317 | * the hotplug driver module. | ||
318 | */ | ||
319 | void pci_hp_create_module_link(struct pci_slot *pci_slot) | ||
320 | { | ||
321 | struct hotplug_slot *slot = pci_slot->hotplug; | ||
322 | struct kobject *kobj = NULL; | ||
323 | int no_warn; | ||
324 | |||
325 | if (!slot || !slot->ops) | ||
326 | return; | ||
327 | kobj = kset_find_obj(module_kset, slot->ops->mod_name); | ||
328 | if (!kobj) | ||
329 | return; | ||
330 | no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); | ||
331 | kobject_put(kobj); | ||
332 | } | ||
333 | EXPORT_SYMBOL_GPL(pci_hp_create_module_link); | ||
334 | |||
335 | /** | ||
336 | * pci_hp_remove_link - remove symbolic link to the hotplug driver module. | ||
337 | * @slot: struct pci_slot | ||
338 | * | ||
339 | * Helper function for pci_hotplug_core.c to remove symbolic link to | ||
340 | * the hotplug driver module. | ||
341 | */ | ||
342 | void pci_hp_remove_module_link(struct pci_slot *pci_slot) | ||
343 | { | ||
344 | sysfs_remove_link(&pci_slot->kobj, "module"); | ||
345 | } | ||
346 | EXPORT_SYMBOL_GPL(pci_hp_remove_module_link); | ||
347 | #endif | ||
348 | |||
310 | static int pci_slot_init(void) | 349 | static int pci_slot_init(void) |
311 | { | 350 | { |
312 | struct kset *pci_bus_kset; | 351 | struct kset *pci_bus_kset; |