diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d46860898e1f..9407aabc77a3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
25 | #include <linux/pci_hotplug.h> | ||
25 | #include <asm-generic/pci-bridge.h> | 26 | #include <asm-generic/pci-bridge.h> |
26 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
27 | #include "pci.h" | 28 | #include "pci.h" |
@@ -3256,6 +3257,35 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | |||
3256 | return 0; | 3257 | return 0; |
3257 | } | 3258 | } |
3258 | 3259 | ||
3260 | static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe) | ||
3261 | { | ||
3262 | int rc = -ENOTTY; | ||
3263 | |||
3264 | if (!hotplug || !try_module_get(hotplug->ops->owner)) | ||
3265 | return rc; | ||
3266 | |||
3267 | if (hotplug->ops->reset_slot) | ||
3268 | rc = hotplug->ops->reset_slot(hotplug, probe); | ||
3269 | |||
3270 | module_put(hotplug->ops->owner); | ||
3271 | |||
3272 | return rc; | ||
3273 | } | ||
3274 | |||
3275 | static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) | ||
3276 | { | ||
3277 | struct pci_dev *pdev; | ||
3278 | |||
3279 | if (dev->subordinate || !dev->slot) | ||
3280 | return -ENOTTY; | ||
3281 | |||
3282 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) | ||
3283 | if (pdev != dev && pdev->slot == dev->slot) | ||
3284 | return -ENOTTY; | ||
3285 | |||
3286 | return pci_reset_hotplug_slot(dev->slot->hotplug, probe); | ||
3287 | } | ||
3288 | |||
3259 | static int __pci_dev_reset(struct pci_dev *dev, int probe) | 3289 | static int __pci_dev_reset(struct pci_dev *dev, int probe) |
3260 | { | 3290 | { |
3261 | int rc; | 3291 | int rc; |
@@ -3278,6 +3308,10 @@ static int __pci_dev_reset(struct pci_dev *dev, int probe) | |||
3278 | if (rc != -ENOTTY) | 3308 | if (rc != -ENOTTY) |
3279 | goto done; | 3309 | goto done; |
3280 | 3310 | ||
3311 | rc = pci_dev_reset_slot_function(dev, probe); | ||
3312 | if (rc != -ENOTTY) | ||
3313 | goto done; | ||
3314 | |||
3281 | rc = pci_parent_bus_reset(dev, probe); | 3315 | rc = pci_parent_bus_reset(dev, probe); |
3282 | done: | 3316 | done: |
3283 | return rc; | 3317 | return rc; |