Commit 96f4e868 authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

[PATCH] ppc64: use newer RTAS call when available

This patch is from Nathan Fontenot <nfont@austin.ibm.com> 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: default avatarNathan Fontenot <nfont@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c6744c49
...@@ -96,6 +96,7 @@ static atomic_t eeh_fail_count; ...@@ -96,6 +96,7 @@ static atomic_t eeh_fail_count;
static int ibm_set_eeh_option; static int ibm_set_eeh_option;
static int ibm_set_slot_reset; static int ibm_set_slot_reset;
static int ibm_read_slot_reset_state; static int ibm_read_slot_reset_state;
static int ibm_read_slot_reset_state2;
static int ibm_slot_error_detail; static int ibm_slot_error_detail;
static int eeh_subsystem_enabled; static int eeh_subsystem_enabled;
...@@ -407,6 +408,27 @@ int eeh_unregister_notifier(struct notifier_block *nb) ...@@ -407,6 +408,27 @@ int eeh_unregister_notifier(struct notifier_block *nb)
return notifier_chain_unregister(&eeh_notifier_chain, nb); return notifier_chain_unregister(&eeh_notifier_chain, nb);
} }
/**
* 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. * 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 * The philosophy of this routine is that it is better to panic and
...@@ -509,7 +531,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) ...@@ -509,7 +531,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
{ {
int ret; int ret;
int rets[2]; int rets[3];
unsigned long flags; unsigned long flags;
int rc, reset_state; int rc, reset_state;
struct eeh_event *event; struct eeh_event *event;
...@@ -540,11 +562,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -540,11 +562,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
atomic_inc(&eeh_fail_count); atomic_inc(&eeh_fail_count);
if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
/* re-read the slot reset state */ /* re-read the slot reset state */
rets[0] = -1; if (read_slot_reset_state(dn, rets) != 0)
rtas_call(ibm_read_slot_reset_state, 3, 3, rets, rets[0] = -1; /* reset state unknown */
dn->eeh_config_addr,
BUID_HI(dn->phb->buid),
BUID_LO(dn->phb->buid));
eeh_panic(dev, rets[0]); eeh_panic(dev, rets[0]);
} }
return 0; return 0;
...@@ -557,10 +576,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) ...@@ -557,10 +576,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* function zero of a multi-function device. * function zero of a multi-function device.
* In any case they must share a common PHB. * In any case they must share a common PHB.
*/ */
ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, ret = read_slot_reset_state(dn, rets);
dn->eeh_config_addr, BUID_HI(dn->phb->buid),
BUID_LO(dn->phb->buid));
if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) {
__get_cpu_var(false_positives)++; __get_cpu_var(false_positives)++;
return 0; return 0;
...@@ -756,6 +772,7 @@ void __init eeh_init(void) ...@@ -756,6 +772,7 @@ void __init eeh_init(void)
ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); 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_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment