aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c419554d0b4b..460d046ab6fe 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3199,7 +3199,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
3199{ 3199{
3200 u16 csr; 3200 u16 csr;
3201 3201
3202 if (!dev->pm_cap) 3202 if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET)
3203 return -ENOTTY; 3203 return -ENOTTY;
3204 3204
3205 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr); 3205 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
@@ -3273,7 +3273,8 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
3273{ 3273{
3274 struct pci_dev *pdev; 3274 struct pci_dev *pdev;
3275 3275
3276 if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) 3276 if (pci_is_root_bus(dev->bus) || dev->subordinate ||
3277 !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
3277 return -ENOTTY; 3278 return -ENOTTY;
3278 3279
3279 list_for_each_entry(pdev, &dev->bus->devices, bus_list) 3280 list_for_each_entry(pdev, &dev->bus->devices, bus_list)
@@ -3307,7 +3308,8 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
3307{ 3308{
3308 struct pci_dev *pdev; 3309 struct pci_dev *pdev;
3309 3310
3310 if (dev->subordinate || !dev->slot) 3311 if (dev->subordinate || !dev->slot ||
3312 dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
3311 return -ENOTTY; 3313 return -ENOTTY;
3312 3314
3313 list_for_each_entry(pdev, &dev->bus->devices, bus_list) 3315 list_for_each_entry(pdev, &dev->bus->devices, bus_list)
@@ -3559,6 +3561,20 @@ int pci_try_reset_function(struct pci_dev *dev)
3559} 3561}
3560EXPORT_SYMBOL_GPL(pci_try_reset_function); 3562EXPORT_SYMBOL_GPL(pci_try_reset_function);
3561 3563
3564/* Do any devices on or below this bus prevent a bus reset? */
3565static bool pci_bus_resetable(struct pci_bus *bus)
3566{
3567 struct pci_dev *dev;
3568
3569 list_for_each_entry(dev, &bus->devices, bus_list) {
3570 if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
3571 (dev->subordinate && !pci_bus_resetable(dev->subordinate)))
3572 return false;
3573 }
3574
3575 return true;
3576}
3577
3562/* Lock devices from the top of the tree down */ 3578/* Lock devices from the top of the tree down */
3563static void pci_bus_lock(struct pci_bus *bus) 3579static void pci_bus_lock(struct pci_bus *bus)
3564{ 3580{
@@ -3609,6 +3625,22 @@ unlock:
3609 return 0; 3625 return 0;
3610} 3626}
3611 3627
3628/* Do any devices on or below this slot prevent a bus reset? */
3629static bool pci_slot_resetable(struct pci_slot *slot)
3630{
3631 struct pci_dev *dev;
3632
3633 list_for_each_entry(dev, &slot->bus->devices, bus_list) {
3634 if (!dev->slot || dev->slot != slot)
3635 continue;
3636 if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
3637 (dev->subordinate && !pci_bus_resetable(dev->subordinate)))
3638 return false;
3639 }
3640
3641 return true;
3642}
3643
3612/* Lock devices from the top of the tree down */ 3644/* Lock devices from the top of the tree down */
3613static void pci_slot_lock(struct pci_slot *slot) 3645static void pci_slot_lock(struct pci_slot *slot)
3614{ 3646{
@@ -3730,7 +3762,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe)
3730{ 3762{
3731 int rc; 3763 int rc;
3732 3764
3733 if (!slot) 3765 if (!slot || !pci_slot_resetable(slot))
3734 return -ENOTTY; 3766 return -ENOTTY;
3735 3767
3736 if (!probe) 3768 if (!probe)
@@ -3822,7 +3854,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot);
3822 3854
3823static int pci_bus_reset(struct pci_bus *bus, int probe) 3855static int pci_bus_reset(struct pci_bus *bus, int probe)
3824{ 3856{
3825 if (!bus->self) 3857 if (!bus->self || !pci_bus_resetable(bus))
3826 return -ENOTTY; 3858 return -ENOTTY;
3827 3859
3828 if (probe) 3860 if (probe)