diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2012-09-07 18:44:16 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-09-09 19:35:42 -0400 |
commit | ff477966c626e440dd1737801ae4d52cf1f22bff (patch) | |
tree | 0b588b5bcc303c0685cd4d0d10925147affaa533 /arch/powerpc/platforms/pseries | |
parent | 9e6d2cf65e3dbaf783917c92c15d31d419b0d648 (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.c | 44 |
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 | */ |
233 | void eeh_slot_error_detail(struct eeh_dev *edev, int severity) | 223 | void 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 | */ |
436 | int eeh_pci_enable(struct eeh_dev *edev, int function) | 431 | int 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; |