aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2012-09-07 18:44:16 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-09 19:35:42 -0400
commitff477966c626e440dd1737801ae4d52cf1f22bff (patch)
tree0b588b5bcc303c0685cd4d0d10925147affaa533 /arch/powerpc/platforms/pseries
parent9e6d2cf65e3dbaf783917c92c15d31d419b0d648 (diff)
powerpc/eeh: I/O enable and log retrival based on PE
The patch refactors the original implementation in order to enable I/O and retrieve EEH log based on PE. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index b5fcecb06731..45723618b1df 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -207,22 +207,12 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
207 } 207 }
208 } 208 }
209 209
210 /* Gather status on devices under the bridge */
211 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
212 struct device_node *child;
213
214 for_each_child_of_node(dn, child) {
215 if (of_node_to_eeh_dev(child))
216 n += eeh_gather_pci_data(of_node_to_eeh_dev(child), buf+n, len-n);
217 }
218 }
219
220 return n; 210 return n;
221} 211}
222 212
223/** 213/**
224 * eeh_slot_error_detail - Generate combined log including driver log and error log 214 * eeh_slot_error_detail - Generate combined log including driver log and error log
225 * @edev: device to report error log for 215 * @pe: EEH PE
226 * @severity: temporary or permanent error log 216 * @severity: temporary or permanent error log
227 * 217 *
228 * This routine should be called to generate the combined log, which 218 * This routine should be called to generate the combined log, which
@@ -230,17 +220,22 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
230 * out from the config space of the corresponding PCI device, while 220 * out from the config space of the corresponding PCI device, while
231 * the error log is fetched through platform dependent function call. 221 * the error log is fetched through platform dependent function call.
232 */ 222 */
233void eeh_slot_error_detail(struct eeh_dev *edev, int severity) 223void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
234{ 224{
235 size_t loglen = 0; 225 size_t loglen = 0;
236 pci_regs_buf[0] = 0; 226 struct eeh_dev *edev;
237 227
238 eeh_pci_enable(edev, EEH_OPT_THAW_MMIO); 228 eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
239 eeh_ops->configure_bridge(eeh_dev_to_of_node(edev)); 229 eeh_ops->configure_bridge(pe);
240 eeh_restore_bars(edev); 230 eeh_pe_restore_bars(pe);
241 loglen = eeh_gather_pci_data(edev, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);
242 231
243 eeh_ops->get_log(eeh_dev_to_of_node(edev), severity, pci_regs_buf, loglen); 232 pci_regs_buf[0] = 0;
233 eeh_pe_for_each_dev(pe, edev) {
234 loglen += eeh_gather_pci_data(edev, pci_regs_buf,
235 EEH_PCI_REGS_LOG_LEN);
236 }
237
238 eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);
244} 239}
245 240
246/** 241/**
@@ -427,23 +422,22 @@ EXPORT_SYMBOL(eeh_check_failure);
427 422
428/** 423/**
429 * eeh_pci_enable - Enable MMIO or DMA transfers for this slot 424 * eeh_pci_enable - Enable MMIO or DMA transfers for this slot
430 * @edev: pci device node 425 * @pe: EEH PE
431 * 426 *
432 * This routine should be called to reenable frozen MMIO or DMA 427 * This routine should be called to reenable frozen MMIO or DMA
433 * so that it would work correctly again. It's useful while doing 428 * so that it would work correctly again. It's useful while doing
434 * recovery or log collection on the indicated device. 429 * recovery or log collection on the indicated device.
435 */ 430 */
436int eeh_pci_enable(struct eeh_dev *edev, int function) 431int eeh_pci_enable(struct eeh_pe *pe, int function)
437{ 432{
438 int rc; 433 int rc;
439 struct device_node *dn = eeh_dev_to_of_node(edev);
440 434
441 rc = eeh_ops->set_option(dn, function); 435 rc = eeh_ops->set_option(pe, function);
442 if (rc) 436 if (rc)
443 printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n", 437 pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n",
444 function, rc, dn->full_name); 438 __func__, function, pe->phb->global_number, pe->addr, rc);
445 439
446 rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC); 440 rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
447 if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) && 441 if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) &&
448 (function == EEH_OPT_THAW_MMIO)) 442 (function == EEH_OPT_THAW_MMIO))
449 return 0; 443 return 0;