diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2013-08-08 16:09:49 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-08-14 17:19:46 -0400 |
commit | 77cb985ad4acbe66a92ead1bb826deffa47dd33f (patch) | |
tree | 788d6b9ec8f701d952c84552fd4d33483c200611 | |
parent | 608c388122c72e1bf11ba8113434eb3d0c40c32d (diff) |
PCI: Split out pci_dev lock/unlock and save/restore
Only cosmetic code changes to existing paths. Expand the comment in
the new pci_dev_save_and_disable() function since there's a lot
hidden in that Command register write.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/pci.c | 55 |
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 | ||
3320 | static 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 | |||
3327 | static void pci_dev_unlock(struct pci_dev *dev) | ||
3328 | { | ||
3329 | device_unlock(&dev->dev); | ||
3330 | pci_cfg_access_unlock(dev); | ||
3331 | } | ||
3332 | |||
3333 | static 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 | |||
3346 | static void pci_dev_restore(struct pci_dev *dev) | ||
3347 | { | ||
3348 | pci_restore_state(dev); | ||
3349 | } | ||
3350 | |||
3320 | static int pci_dev_reset(struct pci_dev *dev, int probe) | 3351 | static 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 | } |