Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 292521
b: refs/heads/master
c: 8d63329
h: refs/heads/master
i:
  292519: 9b35bd6
v: v3
  • Loading branch information
Gavin Shan authored and Benjamin Herrenschmidt committed Mar 9, 2012
1 parent 7fe95f9 commit 0aff839
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 68 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: 2652481f75186940c4608f68c9fd76b32ec9b159
refs/heads/master: 8d633291b4fc0539ecad31f972447104be6953ec
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/include/asm/eeh.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ struct device_node;
#define EEH_RESET_DEACTIVATE 0 /* Deactivate the PE reset */
#define EEH_RESET_HOT 1 /* Hot reset */
#define EEH_RESET_FUNDAMENTAL 3 /* Fundamental reset */
#define EEH_LOG_TEMP 1 /* EEH temporary error log */
#define EEH_LOG_PERM 2 /* EEH permanent error log */

struct eeh_ops {
char *name;
Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/powerpc/include/asm/ppc-pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ void pci_addr_cache_insert_device(struct pci_dev *dev);
void pci_addr_cache_remove_device(struct pci_dev *dev);
void pci_addr_cache_build(void);
struct pci_dev *pci_get_device_by_addr(unsigned long addr);
#define EEH_LOG_TEMP_FAILURE 1
#define EEH_LOG_PERM_FAILURE 2
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 *);
Expand Down
63 changes: 1 addition & 62 deletions trunk/arch/powerpc/platforms/pseries/eeh.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
#define PCI_BUS_RESET_WAIT_MSEC (60*1000)

/* RTAS tokens */
static int ibm_slot_error_detail;
static int ibm_configure_bridge;
static int ibm_configure_pe;

Expand All @@ -100,14 +99,6 @@ EXPORT_SYMBOL(eeh_subsystem_enabled);
/* Lock to avoid races due to multiple reports of an error */
static DEFINE_RAW_SPINLOCK(confirm_error_lock);

/* Buffer for reporting slot-error-detail rtas calls. Its here
* in BSS, and not dynamically alloced, so that it ends up in
* RMO where RTAS can access it.
*/
static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(slot_errbuf_lock);
static int eeh_error_buf_size;

/* Buffer for reporting pci register dumps. Its here in BSS, and
* not dynamically alloced, so that it ends up in RMO where RTAS
* can access it.
Expand All @@ -126,46 +117,6 @@ static unsigned long slot_resets;

#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)

/**
* eeh_rtas_slot_error_detail - Retrieve error log through RTAS call
* @pdn: device node
* @severity: temporary or permanent error log
* @driver_log: driver log to be combined with the retrieved error log
* @loglen: length of driver log
*
* This routine should be called to retrieve error log through the dedicated
* RTAS call.
*/
static void eeh_rtas_slot_error_detail(struct pci_dn *pdn, int severity,
char *driver_log, size_t loglen)
{
int config_addr;
unsigned long flags;
int rc;

/* Log the error with the rtas logger */
spin_lock_irqsave(&slot_errbuf_lock, flags);
memset(slot_errbuf, 0, eeh_error_buf_size);

/* Use PE configuration address, if present */
config_addr = pdn->eeh_config_addr;
if (pdn->eeh_pe_config_addr)
config_addr = pdn->eeh_pe_config_addr;

rc = rtas_call(ibm_slot_error_detail,
8, 1, NULL, config_addr,
BUID_HI(pdn->phb->buid),
BUID_LO(pdn->phb->buid),
virt_to_phys(driver_log), loglen,
virt_to_phys(slot_errbuf),
eeh_error_buf_size,
severity);

if (rc == 0)
log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
spin_unlock_irqrestore(&slot_errbuf_lock, flags);
}

/**
* eeh_gather_pci_data - Copy assorted PCI config space registers to buff
* @pdn: device to report data for
Expand Down Expand Up @@ -282,7 +233,7 @@ void eeh_slot_error_detail(struct pci_dn *pdn, int severity)
eeh_restore_bars(pdn);
loglen = eeh_gather_pci_data(pdn, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);

eeh_rtas_slot_error_detail(pdn, severity, pci_regs_buf, loglen);
eeh_ops->get_log(pdn->node, severity, pci_regs_buf, loglen);
}

/**
Expand Down Expand Up @@ -1071,26 +1022,14 @@ void __init eeh_init(void)
}

raw_spin_lock_init(&confirm_error_lock);
spin_lock_init(&slot_errbuf_lock);

np = of_find_node_by_path("/rtas");
if (np == NULL)
return;

ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
ibm_configure_bridge = rtas_token("ibm,configure-bridge");
ibm_configure_pe = rtas_token("ibm,configure-pe");

eeh_error_buf_size = rtas_token("rtas-error-log-max");
if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
eeh_error_buf_size = 1024;
}
if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
printk(KERN_WARNING "EEH: rtas-error-log-max is bigger than allocated "
"buffer ! (%d vs %d)", eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
}

/* Enable EEH for all adapters. Note that eeh requires buid's */
for (phb = of_find_node_by_name(NULL, "pci"); phb;
phb = of_find_node_by_name(phb, "pci")) {
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/powerpc/platforms/pseries/eeh_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
* don't post the error log until after all dev drivers
* have been informed.
*/
eeh_slot_error_detail(frozen_pdn, EEH_LOG_TEMP_FAILURE);
eeh_slot_error_detail(frozen_pdn, EEH_LOG_TEMP);

/* If all device drivers were EEH-unaware, then shut
* down all of the device drivers, and hope they
Expand Down Expand Up @@ -497,7 +497,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
location, drv_str, pci_str);

perm_error:
eeh_slot_error_detail(frozen_pdn, EEH_LOG_PERM_FAILURE);
eeh_slot_error_detail(frozen_pdn, EEH_LOG_PERM);

/* Notify all devices that they're about to go down. */
pci_walk_bus(frozen_bus, eeh_report_failure, NULL);
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 @@ -56,6 +56,15 @@ static int ibm_get_config_addr_info2;
static int ibm_configure_bridge;
static int ibm_configure_pe;

/*
* Buffer for reporting slot-error-detail rtas calls. Its here
* in BSS, and not dynamically alloced, so that it ends up in
* RMO where RTAS can access it.
*/
static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(slot_errbuf_lock);
static int eeh_error_buf_size;

/**
* pseries_eeh_init - EEH platform dependent initialization
*
Expand Down Expand Up @@ -107,6 +116,19 @@ static int pseries_eeh_init(void)
return -EINVAL;
}

/* Initialize error log lock and size */
spin_lock_init(&slot_errbuf_lock);
eeh_error_buf_size = rtas_token("rtas-error-log-max");
if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
pr_warning("%s: unknown EEH error log size\n",
__func__);
eeh_error_buf_size = 1024;
} else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
pr_warning("%s: EEH error log size %d exceeds the maximal %d\n",
__func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
}

return 0;
}

Expand Down Expand Up @@ -415,7 +437,30 @@ static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
*/
static int pseries_eeh_get_log(struct device_node *dn, int severity, char *drv_log, unsigned long len)
{
return 0;
struct pci_dn *pdn;
int config_addr;
unsigned long flags;
int ret;

pdn = PCI_DN(dn);
spin_lock_irqsave(&slot_errbuf_lock, flags);
memset(slot_errbuf, 0, eeh_error_buf_size);

/* Figure out the PE address */
config_addr = pdn->eeh_config_addr;
if (pdn->eeh_pe_config_addr)
config_addr = pdn->eeh_pe_config_addr;

ret = rtas_call(ibm_slot_error_detail, 8, 1, NULL, config_addr,
BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid),
virt_to_phys(drv_log), len,
virt_to_phys(slot_errbuf), eeh_error_buf_size,
severity);
if (!ret)
log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
spin_unlock_irqrestore(&slot_errbuf_lock, flags);

return ret;
}

/**
Expand Down

0 comments on commit 0aff839

Please sign in to comment.