PCI: Split out pci_dev lock/unlock and save/restore
authorAlex Williamson <alex.williamson@redhat.com>
Thu, 8 Aug 2013 20:09:49 +0000 (14:09 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 14 Aug 2013 21:19:46 +0000 (15:19 -0600)
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>
drivers/pci/pci.c

index 9407aab..d48d9fe 100644 (file)
@@ -3317,22 +3317,49 @@ done:
        return rc;
 }
 
+static void pci_dev_lock(struct pci_dev *dev)
+{
+       pci_cfg_access_lock(dev);
+       /* block PM suspend, driver probe, etc. */
+       device_lock(&dev->dev);
+}
+
+static void pci_dev_unlock(struct pci_dev *dev)
+{
+       device_unlock(&dev->dev);
+       pci_cfg_access_unlock(dev);
+}
+
+static void pci_dev_save_and_disable(struct pci_dev *dev)
+{
+       pci_save_state(dev);
+       /*
+        * Disable the device by clearing the Command register, except for
+        * INTx-disable which is set.  This not only disables MMIO and I/O port
+        * BARs, but also prevents the device from being Bus Master, preventing
+        * DMA from the device including MSI/MSI-X interrupts.  For PCI 2.3
+        * compliant devices, INTx-disable prevents legacy interrupts.
+        */
+       pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
+}
+
+static void pci_dev_restore(struct pci_dev *dev)
+{
+       pci_restore_state(dev);
+}
+
 static int pci_dev_reset(struct pci_dev *dev, int probe)
 {
        int rc;
 
-       if (!probe) {
-               pci_cfg_access_lock(dev);
-               /* block PM suspend, driver probe, etc. */
-               device_lock(&dev->dev);
-       }
+       if (!probe)
+               pci_dev_lock(dev);
 
        rc = __pci_dev_reset(dev, probe);
 
-       if (!probe) {
-               device_unlock(&dev->dev);
-               pci_cfg_access_unlock(dev);
-       }
+       if (!probe)
+               pci_dev_unlock(dev);
+
        return rc;
 }
 /**
@@ -3423,17 +3450,11 @@ int pci_reset_function(struct pci_dev *dev)
        if (rc)
                return rc;
 
-       pci_save_state(dev);
-
-       /*
-        * both INTx and MSI are disabled after the Interrupt Disable bit
-        * is set and the Bus Master bit is cleared.
-        */
-       pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
+       pci_dev_save_and_disable(dev);
 
        rc = pci_dev_reset(dev, 0);
 
-       pci_restore_state(dev);
+       pci_dev_restore(dev);
 
        return rc;
 }