diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 23 |
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 | ||
79 | int pciehp_unconfigure_device(struct slot *p_slot) | 85 | int 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 | } |