aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_pci.c')
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 0e0d0f7f63fd..b07d7cc2d697 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -39,22 +39,26 @@ int pciehp_configure_device(struct slot *p_slot)
39 struct pci_dev *dev; 39 struct pci_dev *dev;
40 struct pci_dev *bridge = p_slot->ctrl->pcie->port; 40 struct pci_dev *bridge = p_slot->ctrl->pcie->port;
41 struct pci_bus *parent = bridge->subordinate; 41 struct pci_bus *parent = bridge->subordinate;
42 int num; 42 int num, ret = 0;
43 struct controller *ctrl = p_slot->ctrl; 43 struct controller *ctrl = p_slot->ctrl;
44 44
45 pci_lock_rescan_remove();
46
45 dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); 47 dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
46 if (dev) { 48 if (dev) {
47 ctrl_err(ctrl, "Device %s already exists " 49 ctrl_err(ctrl, "Device %s already exists "
48 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), 50 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev),
49 pci_domain_nr(parent), parent->number); 51 pci_domain_nr(parent), parent->number);
50 pci_dev_put(dev); 52 pci_dev_put(dev);
51 return -EINVAL; 53 ret = -EINVAL;
54 goto out;
52 } 55 }
53 56
54 num = pci_scan_slot(parent, PCI_DEVFN(0, 0)); 57 num = pci_scan_slot(parent, PCI_DEVFN(0, 0));
55 if (num == 0) { 58 if (num == 0) {
56 ctrl_err(ctrl, "No new device found\n"); 59 ctrl_err(ctrl, "No new device found\n");
57 return -ENODEV; 60 ret = -ENODEV;
61 goto out;
58 } 62 }
59 63
60 list_for_each_entry(dev, &parent->devices, bus_list) 64 list_for_each_entry(dev, &parent->devices, bus_list)
@@ -73,12 +77,14 @@ int pciehp_configure_device(struct slot *p_slot)
73 77
74 pci_bus_add_devices(parent); 78 pci_bus_add_devices(parent);
75 79
76 return 0; 80 out:
81 pci_unlock_rescan_remove();
82 return ret;
77} 83}
78 84
79int pciehp_unconfigure_device(struct slot *p_slot) 85int pciehp_unconfigure_device(struct slot *p_slot)
80{ 86{
81 int ret, rc = 0; 87 int rc = 0;
82 u8 bctl = 0; 88 u8 bctl = 0;
83 u8 presence = 0; 89 u8 presence = 0;
84 struct pci_dev *dev, *temp; 90 struct pci_dev *dev, *temp;
@@ -88,9 +94,9 @@ int pciehp_unconfigure_device(struct slot *p_slot)
88 94
89 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n", 95 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n",
90 __func__, pci_domain_nr(parent), parent->number); 96 __func__, pci_domain_nr(parent), parent->number);
91 ret = pciehp_get_adapter_status(p_slot, &presence); 97 pciehp_get_adapter_status(p_slot, &presence);
92 if (ret) 98
93 presence = 0; 99 pci_lock_rescan_remove();
94 100
95 /* 101 /*
96 * Stopping an SR-IOV PF device removes all the associated VFs, 102 * Stopping an SR-IOV PF device removes all the associated VFs,
@@ -126,5 +132,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
126 pci_dev_put(dev); 132 pci_dev_put(dev);
127 } 133 }
128 134
135 pci_unlock_rescan_remove();
129 return rc; 136 return rc;
130} 137}