Commit 9b3c76f0 authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Handle EEH error based on PE

The patch reworks the current implementation so that the eeh errors
will be handled basing on PE instead of eeh device.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 120dc496
...@@ -174,6 +174,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev); ...@@ -174,6 +174,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
void *eeh_pe_dev_traverse(struct eeh_pe *root, void *eeh_pe_dev_traverse(struct eeh_pe *root,
eeh_traverse_func fn, void *flag); eeh_traverse_func fn, void *flag);
void eeh_pe_restore_bars(struct eeh_pe *pe); void eeh_pe_restore_bars(struct eeh_pe *pe);
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
void * __devinit eeh_dev_init(struct device_node *dn, void *data); void * __devinit eeh_dev_init(struct device_node *dn, void *data);
void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb); void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb);
......
...@@ -32,7 +32,7 @@ struct eeh_event { ...@@ -32,7 +32,7 @@ struct eeh_event {
}; };
int eeh_send_failure_event(struct eeh_pe *pe); int eeh_send_failure_event(struct eeh_pe *pe);
struct eeh_dev *handle_eeh_events(struct eeh_event *); void eeh_handle_event(struct eeh_pe *pe);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* ASM_POWERPC_EEH_EVENT_H */ #endif /* ASM_POWERPC_EEH_EVENT_H */
This diff is collapsed.
...@@ -82,7 +82,7 @@ static int eeh_event_handler(void * dummy) ...@@ -82,7 +82,7 @@ static int eeh_event_handler(void * dummy)
pe->phb->global_number, pe->addr); pe->phb->global_number, pe->addr);
set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */ set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */
handle_eeh_events(event); eeh_handle_event(pe);
eeh_pe_state_clear(pe, EEH_PE_RECOVERING); eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
kfree(event); kfree(event);
......
...@@ -561,3 +561,31 @@ void eeh_pe_restore_bars(struct eeh_pe *pe) ...@@ -561,3 +561,31 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
{ {
eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL); eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
} }
/**
* eeh_pe_bus_get - Retrieve PCI bus according to the given PE
* @pe: EEH PE
*
* Retrieve the PCI bus according to the given PE. Basically,
* there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
* primary PCI bus will be retrieved. The parent bus will be
* returned for BUS PE. However, we don't have associated PCI
* bus for DEVICE PE.
*/
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
{
struct pci_bus *bus = NULL;
struct eeh_dev *edev;
struct pci_dev *pdev;
if (pe->type == EEH_PE_PHB) {
bus = pe->phb->bus;
} else if (pe->type == EEH_PE_BUS) {
edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
pdev = eeh_dev_to_pci_dev(edev);
if (pdev)
bus = pdev->bus;
}
return bus;
}
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