diff mbox

PCI EEH pci_restore_state fix allowing for repeated adapter recovery per state save

Message ID 4C44C85F.2050004@linux.vnet.ibm.com (mailing list archive)
State Rejected, archived
Headers show

Commit Message

Brad Peters July 19, 2010, 9:49 p.m. UTC
None
diff mbox

Patch

diff -uNrp -X linux-2.6.34/Documentation/dontdiff
linux-2.6.34.orig/drivers/pci/pci.c linux-2.6.34/drivers/pci/pci.c
--- linux-2.6.34.orig/drivers/pci/pci.c	2010-05-16 14:17:36.000000000 -0700
+++ linux-2.6.34/drivers/pci/pci.c	2010-05-26 17:16:20.000000000 -0700
@@ -920,19 +920,11 @@  pci_save_state(struct pci_dev *dev)
 	return 0;
 }

-/**
- * pci_restore_state - Restore the saved state of a PCI device
- * @dev: - PCI device that we're dealing with
- */
-int
-pci_restore_state(struct pci_dev *dev)
+static void __pci_restore_state(struct pci_dev *dev)
 {
 	int i;
 	u32 val;

-	if (!dev->state_saved)
-		return 0;
-
 	/* PCI Express register must be restored first */
 	pci_restore_pcie_state(dev);

@@ -953,12 +945,44 @@  pci_restore_state(struct pci_dev *dev)
 	pci_restore_pcix_state(dev);
 	pci_restore_msi_state(dev);
 	pci_restore_iov_state(dev);
+}
+
+
+/**
+ * pci_restore_state - Restore the saved state of a PCI device
+ *                     only if dev->state_saved is not 0. Used by
+ *                     power management suspend/restore routines.
+ * @dev: - PCI device that we're dealing with
+ */
+int
+pci_restore_state(struct pci_dev *dev)
+{
+
+	if (!dev->state_saved)
+		return 0;
+
+	__pci_restore_state(dev);

 	dev->state_saved = false;

 	return 0;
 }

+/**
+ * pci_force_restore_state - Restore the saved state of a PCI device
+ *                           even if dev->state_saved is 0. Used by
+ *                           EEH and AER PCI error recovery.
+ * @dev: - PCI device that we're dealing with
+ */
+int
+pci_force_restore_state(struct pci_dev *dev)
+{
+	__pci_restore_state(dev);
+
+	return 0;
+}
+
+
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
@@ -3039,6 +3063,7 @@  EXPORT_SYMBOL(pci_select_bars);
 EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_save_state);
 EXPORT_SYMBOL(pci_restore_state);
+EXPORT_SYMBOL(pci_force_restore_state);
 EXPORT_SYMBOL(pci_pme_capable);
 EXPORT_SYMBOL(pci_pme_active);
 EXPORT_SYMBOL(pci_wake_from_d3);
diff -uNrp -X linux-2.6.34/Documentation/dontdiff
linux-2.6.34.orig/include/linux/pci.h linux-2.6.34/include/linux/pci.h
--- linux-2.6.34.orig/include/linux/pci.h	2010-05-16 14:17:36.000000000 -0700
+++ linux-2.6.34/include/linux/pci.h	2010-05-26 17:16:21.000000000 -0700
@@ -792,6 +792,7 @@  size_t pci_get_rom_size(struct pci_dev *
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);
 int pci_restore_state(struct pci_dev *dev);
+int pci_force_restore_state(struct pci_dev *dev);
 int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
 int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
@@ -1155,6 +1156,11 @@  static inline int pci_restore_state(stru
 	return 0;
 }

+static inline int pci_force_restore_state(struct pci_dev *dev)
+{
+	return 0;
+}
+
 static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	return 0;