From: Paul Mackerras This patch is from Nathan Fontenot originally. The PPC64 EEH code needs a small update to start using the ibm,read-slot-reset-state2 rtas call if available. The currently used ibm,read-slot-reset-state call will be going away on future machines. This patch attempts to use the newer rtas call if available and falls back the older version otherwise. This will maintain EEH slot checking capabilities on all future and current firmware levels. Signed-off-by: Nathan Fontenot Signed-off-by: Paul Mackerras Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/kernel/eeh.c | 37 +++++++++++++++++++++++++++---------- 1 files changed, 27 insertions(+), 10 deletions(-) diff -puN arch/ppc64/kernel/eeh.c~ppc64-use-newer-rtas-call-when-available arch/ppc64/kernel/eeh.c --- 25/arch/ppc64/kernel/eeh.c~ppc64-use-newer-rtas-call-when-available 2005-01-05 15:36:39.530576472 -0800 +++ 25-akpm/arch/ppc64/kernel/eeh.c 2005-01-05 15:36:39.535575712 -0800 @@ -96,6 +96,7 @@ static atomic_t eeh_fail_count; static int ibm_set_eeh_option; static int ibm_set_slot_reset; static int ibm_read_slot_reset_state; +static int ibm_read_slot_reset_state2; static int ibm_slot_error_detail; static int eeh_subsystem_enabled; @@ -408,6 +409,27 @@ int eeh_unregister_notifier(struct notif } /** + * read_slot_reset_state - Read the reset state of a device node's slot + * @dn: device node to read + * @rets: array to return results in + */ +static int read_slot_reset_state(struct device_node *dn, int rets[]) +{ + int token, outputs; + + if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { + token = ibm_read_slot_reset_state2; + outputs = 4; + } else { + token = ibm_read_slot_reset_state; + outputs = 3; + } + + return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); +} + +/** * eeh_panic - call panic() for an eeh event that cannot be handled. * The philosophy of this routine is that it is better to panic and * halt the OS than it is to risk possible data corruption by @@ -509,7 +531,7 @@ static inline unsigned long eeh_token_to int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) { int ret; - int rets[2]; + int rets[3]; unsigned long flags; int rc, reset_state; struct eeh_event *event; @@ -540,11 +562,8 @@ int eeh_dn_check_failure(struct device_n atomic_inc(&eeh_fail_count); if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { /* re-read the slot reset state */ - rets[0] = -1; - rtas_call(ibm_read_slot_reset_state, 3, 3, rets, - dn->eeh_config_addr, - BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid)); + if (read_slot_reset_state(dn, rets) != 0) + rets[0] = -1; /* reset state unknown */ eeh_panic(dev, rets[0]); } return 0; @@ -557,10 +576,7 @@ int eeh_dn_check_failure(struct device_n * function zero of a multi-function device. * In any case they must share a common PHB. */ - ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, - dn->eeh_config_addr, BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid)); - + ret = read_slot_reset_state(dn, rets); if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { __get_cpu_var(false_positives)++; return 0; @@ -756,6 +772,7 @@ void __init eeh_init(void) ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); + ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); _