| From 99c965dd9ee1a004efc083c3d760ba982bb76adf Mon Sep 17 00:00:00 2001 |
| From: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com> |
| Date: Wed, 25 Nov 2009 20:13:43 -0200 |
| Subject: SCSI: ipr: fix EEH recovery |
| |
| From: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com> |
| |
| commit 99c965dd9ee1a004efc083c3d760ba982bb76adf upstream. |
| |
| After commits c82f63e411f1b58427c103bd95af2863b1c96dd1 (PCI: check saved |
| state before restore) and 4b77b0a2ba27d64f58f16d8d4d48d8319dda36ff (PCI: |
| Clear saved_state after the state has been restored) PCI drivers are |
| prevented from restoring the device standard configuration registers |
| twice in a row. These changes introduced a regression on ipr EEH |
| recovery. |
| |
| The ipr device driver saves the PCI state only during the device probe |
| and restores it on ipr_reset_restore_cfg_space() during IOA resets. This |
| behavior is causing the EEH recovery to fail after the second error |
| detected, since the registers are not being restored. |
| |
| One possible solution would be saving the registers after restoring |
| them. The problem with this approach is that while recovering from an |
| EEH error if pci_save_state() results in an EEH error, the adapter/slot |
| will be reset, and end up back in ipr_reset_restore_cfg_space(), but it |
| won't have a valid saved state to restore, so pci_restore_state() will |
| fail. |
| |
| The following patch introduces a workaround for this problem, hacking |
| around the PCI API by setting pdev->state_saved = true before we do the |
| restore. It fixes the EEH regression and prevents that we hit another |
| EEH error during EEH recovery. |
| |
| |
| [jejb: fix is a hack ... Jesse and Rafael will fix properly] |
| Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com> |
| Acked-by: Brian King <brking@linux.vnet.ibm.com> |
| Cc: Jesse Barnes <jbarnes@virtuousgeek.org> |
| Signed-off-by: James Bottomley <James.Bottomley@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/scsi/ipr.c | 1 + |
| 1 file changed, 1 insertion(+) |
| |
| --- a/drivers/scsi/ipr.c |
| +++ b/drivers/scsi/ipr.c |
| @@ -6516,6 +6516,7 @@ static int ipr_reset_restore_cfg_space(s |
| int rc; |
| |
| ENTER; |
| + ioa_cfg->pdev->state_saved = true; |
| rc = pci_restore_state(ioa_cfg->pdev); |
| |
| if (rc != PCIBIOS_SUCCESSFUL) { |