Skip to content

Commit

Permalink
[POWERPC] EEH: Power4 systems sometimes need multiple resets.
Browse files Browse the repository at this point in the history
On detection of an EEH error, some Power4 systems seem to occasionally
want to be reset twice before they report themselves as fully recovered.
This patch re-arranges the code to attempt additional resets if the first
one doesn't take.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Linas Vepstas authored and Paul Mackerras committed Sep 22, 2006
1 parent 3d574ab commit e102926
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions arch/powerpc/platforms/pseries/eeh.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ eeh_slot_availability(struct pci_dn *pdn)

printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n",
rc, rets[0], rets[1], rets[2]);
return -1;
return -2;
}

/**
Expand Down Expand Up @@ -546,11 +546,10 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
BUID_HI(pdn->phb->buid),
BUID_LO(pdn->phb->buid),
state);
if (rc) {
printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n",
if (rc)
printk (KERN_WARNING "EEH: Unable to reset the failed slot,"
" (%d) #RST=%d dn=%s\n",
rc, state, pdn->node->full_name);
return;
}
}

/**
Expand All @@ -560,11 +559,8 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
* Return 0 if success, else a non-zero value.
*/

int
rtas_set_slot_reset(struct pci_dn *pdn)
static void __rtas_set_slot_reset(struct pci_dn *pdn)
{
int i, rc;

rtas_pci_slot_reset (pdn, 1);

/* The PCI bus requires that the reset be held high for at least
Expand All @@ -585,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn)
* up traffic. */
#define PCI_BUS_SETTLE_TIME_MSEC 1800
msleep (PCI_BUS_SETTLE_TIME_MSEC);
}

int rtas_set_slot_reset(struct pci_dn *pdn)
{
int i, rc;

__rtas_set_slot_reset(pdn);

/* Now double check with the firmware to make sure the device is
* ready to be used; if not, wait for recovery. */
for (i=0; i<10; i++) {
rc = eeh_slot_availability (pdn);
if (rc < 0)
printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
if (rc == 0)
return 0;
if (rc < 0)

if (rc == -2) {
printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n",
i, pdn->node->full_name);
__rtas_set_slot_reset(pdn);
continue;
}

if (rc < 0) {
printk (KERN_ERR "EEH: unrecoverable slot failure %s\n",
pdn->node->full_name);
return -1;
}

msleep (rc+100);
}
Expand Down

0 comments on commit e102926

Please sign in to comment.