Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 292519
b: refs/heads/master
c: b0e5f74
h: refs/heads/master
i:
  292517: fc6f51b
  292515: fef7f62
  292511: 6c5594a
v: v3
  • Loading branch information
Gavin Shan authored and Benjamin Herrenschmidt committed Mar 9, 2012
1 parent 3d73739 commit 9b35bd6
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: eb594a4754e71e41c048e0f1559bb6f13dab7070
refs/heads/master: b0e5f742f1816bebedabeb6844be1a598bd50a91
1 change: 0 additions & 1 deletion trunk/arch/powerpc/include/asm/ppc-pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ struct pci_dev *pci_get_device_by_addr(unsigned long addr);
void eeh_slot_error_detail (struct pci_dn *pdn, int severity);
int eeh_pci_enable(struct pci_dn *pdn, int function);
int eeh_reset_pe(struct pci_dn *);
int eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs);
void eeh_restore_bars(struct pci_dn *);
void eeh_configure_bridge(struct pci_dn *);
int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
Expand Down
46 changes: 2 additions & 44 deletions trunk/arch/powerpc/platforms/pseries/eeh.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,48 +286,6 @@ void eeh_slot_error_detail(struct pci_dn *pdn, int severity)
eeh_rtas_slot_error_detail(pdn, severity, pci_regs_buf, loglen);
}

/**
* eeh_wait_for_slot_status - Returns error status of slot
* @pdn: pci device node
* @max_wait_msecs: maximum number to millisecs to wait
*
* Return negative value if a permanent error, else return
* Partition Endpoint (PE) status value.
*
* If @max_wait_msecs is positive, then this routine will
* sleep until a valid status can be obtained, or until
* the max allowed wait time is exceeded, in which case
* a -2 is returned.
*/
int eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs)
{
int rc;
int mwait;

while (1) {
rc = eeh_ops->get_state(pdn->node, &mwait);
if (rc != EEH_STATE_UNAVAILABLE)
return rc;

if (max_wait_msecs <= 0) break;

if (mwait <= 0) {
printk(KERN_WARNING "EEH: Firmware returned bad wait value=%d\n",
mwait);
mwait = 1000;
} else if (mwait > 300*1000) {
printk(KERN_WARNING "EEH: Firmware is taking too long, time=%d\n",
mwait);
mwait = 300*1000;
}
max_wait_msecs -= mwait;
msleep(mwait);
}

printk(KERN_WARNING "EEH: Timed out waiting for slot status\n");
return -2;
}

/**
* eeh_token_to_phys - Convert EEH address token to phys address
* @token: I/O token, should be address in the form 0xA....
Expand Down Expand Up @@ -640,7 +598,7 @@ int eeh_pci_enable(struct pci_dn *pdn, int function)
printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n",
function, rc, pdn->node->full_name);

rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
rc = eeh_ops->wait_state(pdn->node, PCI_BUS_RESET_WAIT_MSEC);
if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) &&
(function == EEH_OPT_THAW_MMIO))
return 0;
Expand Down Expand Up @@ -838,7 +796,7 @@ int eeh_reset_pe(struct pci_dn *pdn)
for (i=0; i<3; i++) {
eeh_reset_pe_once(pdn);

rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
rc = eeh_ops->wait_state(pdn->node, PCI_BUS_RESET_WAIT_MSEC);
if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE))
return 0;

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/platforms/pseries/eeh_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)

/* Get the current PCI slot state. This can take a long time,
* sometimes over 3 seconds for certain systems. */
rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000);
rc = eeh_ops->wait_state(frozen_pdn->node, MAX_WAIT_FOR_RECOVERY*1000);
if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
printk(KERN_WARNING "EEH: Permanent failure\n");
goto hard_fail;
Expand Down
47 changes: 46 additions & 1 deletion trunk/arch/powerpc/platforms/pseries/eeh_pseries.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,52 @@ static int pseries_eeh_reset(struct device_node *dn, int option)
*/
static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
{
return 0;
int ret;
int mwait;

/*
* According to PAPR, the state of PE might be temporarily
* unavailable. Under the circumstance, we have to wait
* for indicated time determined by firmware. The maximal
* wait time is 5 minutes, which is acquired from the original
* EEH implementation. Also, the original implementation
* also defined the minimal wait time as 1 second.
*/
#define EEH_STATE_MIN_WAIT_TIME (1000)
#define EEH_STATE_MAX_WAIT_TIME (300 * 1000)

while (1) {
ret = pseries_eeh_get_state(dn, &mwait);

/*
* If the PE's state is temporarily unavailable,
* we have to wait for the specified time. Otherwise,
* the PE's state will be returned immediately.
*/
if (ret != EEH_STATE_UNAVAILABLE)
return ret;

if (max_wait <= 0) {
pr_warning("%s: Timeout when getting PE's state (%d)\n",
__func__, max_wait);
return EEH_STATE_NOT_SUPPORT;
}

if (mwait <= 0) {
pr_warning("%s: Firmware returned bad wait value %d\n",
__func__, mwait);
mwait = EEH_STATE_MIN_WAIT_TIME;
} else if (mwait > EEH_STATE_MAX_WAIT_TIME) {
pr_warning("%s: Firmware returned too long wait value %d\n",
__func__, mwait);
mwait = EEH_STATE_MAX_WAIT_TIME;
}

max_wait -= mwait;
msleep(mwait);
}

return EEH_STATE_NOT_SUPPORT;
}

/**
Expand Down

0 comments on commit 9b35bd6

Please sign in to comment.