aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2008-10-20 19:40:57 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-10-22 19:42:38 -0400
commit95cb9093960b6249fdbe7417bf513a1358aaa51a (patch)
tree8cfe1c98235ff947685940b328e73c39809751fe /drivers
parent828f37683e6d3ab5912989df0d04201db7ad798e (diff)
PCI Hotplug: serialize pci_hp_register and pci_hp_deregister
Convert the pci_hotplug_slot_list_lock, which only protected the list of hotplug slots, to a pci_hp_mutex which now protects both interfaces. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 1cdeb642fdcf..e71524825180 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -37,6 +37,7 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/mount.h> 38#include <linux/mount.h>
39#include <linux/namei.h> 39#include <linux/namei.h>
40#include <linux/mutex.h>
40#include <linux/pci.h> 41#include <linux/pci.h>
41#include <linux/pci_hotplug.h> 42#include <linux/pci_hotplug.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
@@ -61,7 +62,7 @@ static int debug;
61////////////////////////////////////////////////////////////////// 62//////////////////////////////////////////////////////////////////
62 63
63static LIST_HEAD(pci_hotplug_slot_list); 64static LIST_HEAD(pci_hotplug_slot_list);
64static DEFINE_SPINLOCK(pci_hotplug_slot_list_lock); 65static DEFINE_MUTEX(pci_hp_mutex);
65 66
66/* these strings match up with the values in pci_bus_speed */ 67/* these strings match up with the values in pci_bus_speed */
67static char *pci_bus_speed_strings[] = { 68static char *pci_bus_speed_strings[] = {
@@ -530,16 +531,12 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
530 struct hotplug_slot *slot; 531 struct hotplug_slot *slot;
531 struct list_head *tmp; 532 struct list_head *tmp;
532 533
533 spin_lock(&pci_hotplug_slot_list_lock);
534 list_for_each (tmp, &pci_hotplug_slot_list) { 534 list_for_each (tmp, &pci_hotplug_slot_list) {
535 slot = list_entry (tmp, struct hotplug_slot, slot_list); 535 slot = list_entry (tmp, struct hotplug_slot, slot_list);
536 if (strcmp(slot->name, name) == 0) 536 if (strcmp(slot->name, name) == 0)
537 goto out; 537 return slot;
538 } 538 }
539 slot = NULL; 539 return NULL;
540out:
541 spin_unlock(&pci_hotplug_slot_list_lock);
542 return slot;
543} 540}
544 541
545/** 542/**
@@ -570,9 +567,13 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
570 return -EINVAL; 567 return -EINVAL;
571 } 568 }
572 569
570 mutex_lock(&pci_hp_mutex);
571
573 /* Check if we have already registered a slot with the same name. */ 572 /* Check if we have already registered a slot with the same name. */
574 if (get_slot_from_name(name)) 573 if (get_slot_from_name(name)) {
575 return -EEXIST; 574 result = -EEXIST;
575 goto out;
576 }
576 577
577 /* 578 /*
578 * No problems if we call this interface from both ACPI_PCI_SLOT 579 * No problems if we call this interface from both ACPI_PCI_SLOT
@@ -580,13 +581,15 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
580 * pci_slot, the interface will simply bump the refcount. 581 * pci_slot, the interface will simply bump the refcount.
581 */ 582 */
582 pci_slot = pci_create_slot(bus, slot_nr, name, slot); 583 pci_slot = pci_create_slot(bus, slot_nr, name, slot);
583 if (IS_ERR(pci_slot)) 584 if (IS_ERR(pci_slot)) {
584 return PTR_ERR(pci_slot); 585 result = PTR_ERR(pci_slot);
586 goto cleanup;
587 }
585 588
586 if (pci_slot->hotplug) { 589 if (pci_slot->hotplug) {
587 dbg("%s: already claimed\n", __func__); 590 dbg("%s: already claimed\n", __func__);
588 pci_destroy_slot(pci_slot); 591 result = -EBUSY;
589 return -EBUSY; 592 goto cleanup;
590 } 593 }
591 594
592 slot->pci_slot = pci_slot; 595 slot->pci_slot = pci_slot;
@@ -597,21 +600,21 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
597 */ 600 */
598 if (strcmp(kobject_name(&pci_slot->kobj), name)) { 601 if (strcmp(kobject_name(&pci_slot->kobj), name)) {
599 result = kobject_rename(&pci_slot->kobj, name); 602 result = kobject_rename(&pci_slot->kobj, name);
600 if (result) { 603 if (result)
601 pci_destroy_slot(pci_slot); 604 goto cleanup;
602 return result;
603 }
604 } 605 }
605 606
606 spin_lock(&pci_hotplug_slot_list_lock);
607 list_add(&slot->slot_list, &pci_hotplug_slot_list); 607 list_add(&slot->slot_list, &pci_hotplug_slot_list);
608 spin_unlock(&pci_hotplug_slot_list_lock);
609 608
610 result = fs_add_slot(pci_slot); 609 result = fs_add_slot(pci_slot);
611 kobject_uevent(&pci_slot->kobj, KOBJ_ADD); 610 kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
612 dbg("Added slot %s to the list\n", name); 611 dbg("Added slot %s to the list\n", name);
613 612out:
613 mutex_unlock(&pci_hp_mutex);
614 return result; 614 return result;
615cleanup:
616 pci_destroy_slot(pci_slot);
617 goto out;
615} 618}
616 619
617/** 620/**
@@ -631,13 +634,14 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)
631 if (!hotplug) 634 if (!hotplug)
632 return -ENODEV; 635 return -ENODEV;
633 636
637 mutex_lock(&pci_hp_mutex);
634 temp = get_slot_from_name(hotplug->name); 638 temp = get_slot_from_name(hotplug->name);
635 if (temp != hotplug) 639 if (temp != hotplug) {
640 mutex_unlock(&pci_hp_mutex);
636 return -ENODEV; 641 return -ENODEV;
642 }
637 643
638 spin_lock(&pci_hotplug_slot_list_lock);
639 list_del(&hotplug->slot_list); 644 list_del(&hotplug->slot_list);
640 spin_unlock(&pci_hotplug_slot_list_lock);
641 645
642 slot = hotplug->pci_slot; 646 slot = hotplug->pci_slot;
643 fs_remove_slot(slot); 647 fs_remove_slot(slot);
@@ -646,6 +650,7 @@ int pci_hp_deregister(struct hotplug_slot *hotplug)
646 hotplug->release(hotplug); 650 hotplug->release(hotplug);
647 slot->hotplug = NULL; 651 slot->hotplug = NULL;
648 pci_destroy_slot(slot); 652 pci_destroy_slot(slot);
653 mutex_unlock(&pci_hp_mutex);
649 654
650 return 0; 655 return 0;
651} 656}