aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9407aabc77a3..d48d9febc241 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3317,22 +3317,49 @@ done:
3317 return rc; 3317 return rc;
3318} 3318}
3319 3319
3320static void pci_dev_lock(struct pci_dev *dev)
3321{
3322 pci_cfg_access_lock(dev);
3323 /* block PM suspend, driver probe, etc. */
3324 device_lock(&dev->dev);
3325}
3326
3327static void pci_dev_unlock(struct pci_dev *dev)
3328{
3329 device_unlock(&dev->dev);
3330 pci_cfg_access_unlock(dev);
3331}
3332
3333static void pci_dev_save_and_disable(struct pci_dev *dev)
3334{
3335 pci_save_state(dev);
3336 /*
3337 * Disable the device by clearing the Command register, except for
3338 * INTx-disable which is set. This not only disables MMIO and I/O port
3339 * BARs, but also prevents the device from being Bus Master, preventing
3340 * DMA from the device including MSI/MSI-X interrupts. For PCI 2.3
3341 * compliant devices, INTx-disable prevents legacy interrupts.
3342 */
3343 pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
3344}
3345
3346static void pci_dev_restore(struct pci_dev *dev)
3347{
3348 pci_restore_state(dev);
3349}
3350
3320static int pci_dev_reset(struct pci_dev *dev, int probe) 3351static int pci_dev_reset(struct pci_dev *dev, int probe)
3321{ 3352{
3322 int rc; 3353 int rc;
3323 3354
3324 if (!probe) { 3355 if (!probe)
3325 pci_cfg_access_lock(dev); 3356 pci_dev_lock(dev);
3326 /* block PM suspend, driver probe, etc. */
3327 device_lock(&dev->dev);
3328 }
3329 3357
3330 rc = __pci_dev_reset(dev, probe); 3358 rc = __pci_dev_reset(dev, probe);
3331 3359
3332 if (!probe) { 3360 if (!probe)
3333 device_unlock(&dev->dev); 3361 pci_dev_unlock(dev);
3334 pci_cfg_access_unlock(dev); 3362
3335 }
3336 return rc; 3363 return rc;
3337} 3364}
3338/** 3365/**
@@ -3423,17 +3450,11 @@ int pci_reset_function(struct pci_dev *dev)
3423 if (rc) 3450 if (rc)
3424 return rc; 3451 return rc;
3425 3452
3426 pci_save_state(dev); 3453 pci_dev_save_and_disable(dev);
3427
3428 /*
3429 * both INTx and MSI are disabled after the Interrupt Disable bit
3430 * is set and the Bus Master bit is cleared.
3431 */
3432 pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
3433 3454
3434 rc = pci_dev_reset(dev, 0); 3455 rc = pci_dev_reset(dev, 0);
3435 3456
3436 pci_restore_state(dev); 3457 pci_dev_restore(dev);
3437 3458
3438 return rc; 3459 return rc;
3439} 3460}