Commit e762bb89 authored by Sam Bobroff's avatar Sam Bobroff Committed by Michael Ellerman

powerpc/eeh: Cleanup eeh_pe_state_mark()

Currently, eeh_pe_state_mark() marks a PE (and it's children) with a
state and then performs additional processing if that state included
EEH_PE_ISOLATED.

The state parameter is always a constant at the call site, so
rearrange eeh_pe_state_mark() into two functions and just call the
appropriate one at each site.
Signed-off-by: default avatarSam Bobroff <sbobroff@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent eed4bdbe
...@@ -58,6 +58,7 @@ void eeh_save_bars(struct eeh_dev *edev); ...@@ -58,6 +58,7 @@ void eeh_save_bars(struct eeh_dev *edev);
int rtas_write_config(struct pci_dn *, int where, int size, u32 val); int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
void eeh_pe_state_mark(struct eeh_pe *pe, int state); void eeh_pe_state_mark(struct eeh_pe *pe, int state);
void eeh_pe_mark_isolated(struct eeh_pe *pe);
void eeh_pe_state_clear(struct eeh_pe *pe, int state); void eeh_pe_state_clear(struct eeh_pe *pe, int state);
void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state); void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state);
void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode); void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode);
......
...@@ -404,7 +404,7 @@ static int eeh_phb_check_failure(struct eeh_pe *pe) ...@@ -404,7 +404,7 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
} }
/* Isolate the PHB and send event */ /* Isolate the PHB and send event */
eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(phb_pe);
eeh_serialize_unlock(flags); eeh_serialize_unlock(flags);
pr_err("EEH: PHB#%x failure detected, location: %s\n", pr_err("EEH: PHB#%x failure detected, location: %s\n",
...@@ -563,7 +563,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) ...@@ -563,7 +563,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
* with other functions on this device, and functions under * with other functions on this device, and functions under
* bridges. * bridges.
*/ */
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
eeh_serialize_unlock(flags); eeh_serialize_unlock(flags);
/* Most EEH events are due to device driver bugs. Having /* Most EEH events are due to device driver bugs. Having
...@@ -830,7 +830,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat ...@@ -830,7 +830,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
eeh_pe_state_clear(pe, EEH_PE_ISOLATED); eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
break; break;
case pcie_hot_reset: case pcie_hot_reset:
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
...@@ -839,7 +839,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat ...@@ -839,7 +839,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
eeh_ops->reset(pe, EEH_RESET_HOT); eeh_ops->reset(pe, EEH_RESET_HOT);
break; break;
case pcie_warm_reset: case pcie_warm_reset:
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
......
...@@ -1029,7 +1029,7 @@ void eeh_handle_special_event(void) ...@@ -1029,7 +1029,7 @@ void eeh_handle_special_event(void)
phb_pe = eeh_phb_pe_get(hose); phb_pe = eeh_phb_pe_get(hose);
if (!phb_pe) continue; if (!phb_pe) continue;
eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(phb_pe);
} }
eeh_serialize_unlock(flags); eeh_serialize_unlock(flags);
...@@ -1044,11 +1044,9 @@ void eeh_handle_special_event(void) ...@@ -1044,11 +1044,9 @@ void eeh_handle_special_event(void)
/* Purge all events of the PHB */ /* Purge all events of the PHB */
eeh_remove_event(pe, true); eeh_remove_event(pe, true);
if (rc == EEH_NEXT_ERR_DEAD_PHB) if (rc != EEH_NEXT_ERR_DEAD_PHB)
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
else eeh_pe_mark_isolated(pe);
eeh_pe_state_mark(pe,
EEH_PE_ISOLATED | EEH_PE_RECOVERING);
eeh_serialize_unlock(flags); eeh_serialize_unlock(flags);
......
...@@ -540,56 +540,50 @@ void eeh_pe_update_time_stamp(struct eeh_pe *pe) ...@@ -540,56 +540,50 @@ void eeh_pe_update_time_stamp(struct eeh_pe *pe)
} }
/** /**
* __eeh_pe_state_mark - Mark the state for the PE * eeh_pe_state_mark - Mark specified state for PE and its associated device
* @data: EEH PE * @pe: EEH PE
* @flag: state
* *
* The function is used to mark the indicated state for the given * EEH error affects the current PE and its child PEs. The function
* PE. Also, the associated PCI devices will be put into IO frozen * is used to mark appropriate state for the affected PEs and the
* state as well. * associated devices.
*/ */
static void *__eeh_pe_state_mark(struct eeh_pe *pe, void *flag) void eeh_pe_state_mark(struct eeh_pe *root, int state)
{ {
int state = *((int *)flag); struct eeh_pe *pe;
struct eeh_dev *edev, *tmp;
struct pci_dev *pdev;
/* Keep the state of permanently removed PE intact */
if (pe->state & EEH_PE_REMOVED)
return NULL;
eeh_for_each_pe(root, pe)
if (!(pe->state & EEH_PE_REMOVED))
pe->state |= state; pe->state |= state;
}
EXPORT_SYMBOL_GPL(eeh_pe_state_mark);
/* Offline PCI devices if applicable */ /**
if (!(state & EEH_PE_ISOLATED)) * eeh_pe_mark_isolated
return NULL; * @pe: EEH PE
*
* Record that a PE has been isolated by marking the PE and it's children as
* EEH_PE_ISOLATED (and EEH_PE_CFG_BLOCKED, if required) and their PCI devices
* as pci_channel_io_frozen.
*/
void eeh_pe_mark_isolated(struct eeh_pe *root)
{
struct eeh_pe *pe;
struct eeh_dev *edev;
struct pci_dev *pdev;
eeh_pe_for_each_dev(pe, edev, tmp) { eeh_pe_state_mark(root, EEH_PE_ISOLATED);
eeh_for_each_pe(root, pe) {
list_for_each_entry(edev, &pe->edevs, entry) {
pdev = eeh_dev_to_pci_dev(edev); pdev = eeh_dev_to_pci_dev(edev);
if (pdev) if (pdev)
pdev->error_state = pci_channel_io_frozen; pdev->error_state = pci_channel_io_frozen;
} }
/* Block PCI config access if required */ /* Block PCI config access if required */
if (pe->state & EEH_PE_CFG_RESTRICTED) if (pe->state & EEH_PE_CFG_RESTRICTED)
pe->state |= EEH_PE_CFG_BLOCKED; pe->state |= EEH_PE_CFG_BLOCKED;
}
return NULL;
}
/**
* eeh_pe_state_mark - Mark specified state for PE and its associated device
* @pe: EEH PE
*
* EEH error affects the current PE and its child PEs. The function
* is used to mark appropriate state for the affected PEs and the
* associated devices.
*/
void eeh_pe_state_mark(struct eeh_pe *pe, int state)
{
eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
} }
EXPORT_SYMBOL_GPL(eeh_pe_state_mark); EXPORT_SYMBOL_GPL(eeh_pe_mark_isolated);
static void *__eeh_pe_dev_mode_mark(struct eeh_dev *edev, void *flag) static void *__eeh_pe_dev_mode_mark(struct eeh_dev *edev, void *flag)
{ {
......
...@@ -590,7 +590,7 @@ static int pnv_eeh_get_phb_state(struct eeh_pe *pe) ...@@ -590,7 +590,7 @@ static int pnv_eeh_get_phb_state(struct eeh_pe *pe)
EEH_STATE_MMIO_ENABLED | EEH_STATE_MMIO_ENABLED |
EEH_STATE_DMA_ENABLED); EEH_STATE_DMA_ENABLED);
} else if (!(pe->state & EEH_PE_ISOLATED)) { } else if (!(pe->state & EEH_PE_ISOLATED)) {
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
pnv_eeh_get_phb_diag(pe); pnv_eeh_get_phb_diag(pe);
if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
...@@ -692,7 +692,7 @@ static int pnv_eeh_get_pe_state(struct eeh_pe *pe) ...@@ -692,7 +692,7 @@ static int pnv_eeh_get_pe_state(struct eeh_pe *pe)
if (phb->freeze_pe) if (phb->freeze_pe)
phb->freeze_pe(phb, pe->addr); phb->freeze_pe(phb, pe->addr);
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
pnv_eeh_get_phb_diag(pe); pnv_eeh_get_phb_diag(pe);
if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
...@@ -1597,7 +1597,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe) ...@@ -1597,7 +1597,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
if ((ret == EEH_NEXT_ERR_FROZEN_PE || if ((ret == EEH_NEXT_ERR_FROZEN_PE ||
ret == EEH_NEXT_ERR_FENCED_PHB) && ret == EEH_NEXT_ERR_FENCED_PHB) &&
!((*pe)->state & EEH_PE_ISOLATED)) { !((*pe)->state & EEH_PE_ISOLATED)) {
eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(*pe);
pnv_eeh_get_phb_diag(*pe); pnv_eeh_get_phb_diag(*pe);
if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
...@@ -1626,7 +1626,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe) ...@@ -1626,7 +1626,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
} }
/* We possibly migrate to another PE */ /* We possibly migrate to another PE */
eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(*pe);
} }
/* /*
......
...@@ -736,7 +736,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data) ...@@ -736,7 +736,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
pe = edev ? edev->pe : NULL; pe = edev ? edev->pe : NULL;
if (pe) { if (pe) {
eeh_serialize_lock(&flags); eeh_serialize_lock(&flags);
eeh_pe_state_mark(pe, EEH_PE_ISOLATED); eeh_pe_mark_isolated(pe);
eeh_serialize_unlock(flags); eeh_serialize_unlock(flags);
eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE); eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
} }
......
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