mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 09:31:14 +00:00
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: Sam Bobroff <sbobroff@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
eed4bdbeec
commit
e762bb891a
6 changed files with 48 additions and 55 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
* 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
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
/* 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);
|
||||||
|
|
||||||
|
|
|
@ -539,44 +539,6 @@ void eeh_pe_update_time_stamp(struct eeh_pe *pe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* __eeh_pe_state_mark - Mark the state for the PE
|
|
||||||
* @data: EEH PE
|
|
||||||
* @flag: state
|
|
||||||
*
|
|
||||||
* The function is used to mark the indicated state for the given
|
|
||||||
* PE. Also, the associated PCI devices will be put into IO frozen
|
|
||||||
* state as well.
|
|
||||||
*/
|
|
||||||
static void *__eeh_pe_state_mark(struct eeh_pe *pe, void *flag)
|
|
||||||
{
|
|
||||||
int state = *((int *)flag);
|
|
||||||
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;
|
|
||||||
|
|
||||||
pe->state |= state;
|
|
||||||
|
|
||||||
/* Offline PCI devices if applicable */
|
|
||||||
if (!(state & EEH_PE_ISOLATED))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
eeh_pe_for_each_dev(pe, edev, tmp) {
|
|
||||||
pdev = eeh_dev_to_pci_dev(edev);
|
|
||||||
if (pdev)
|
|
||||||
pdev->error_state = pci_channel_io_frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Block PCI config access if required */
|
|
||||||
if (pe->state & EEH_PE_CFG_RESTRICTED)
|
|
||||||
pe->state |= EEH_PE_CFG_BLOCKED;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eeh_pe_state_mark - Mark specified state for PE and its associated device
|
* eeh_pe_state_mark - Mark specified state for PE and its associated device
|
||||||
* @pe: EEH PE
|
* @pe: EEH PE
|
||||||
|
@ -585,12 +547,44 @@ static void *__eeh_pe_state_mark(struct eeh_pe *pe, void *flag)
|
||||||
* is used to mark appropriate state for the affected PEs and the
|
* is used to mark appropriate state for the affected PEs and the
|
||||||
* associated devices.
|
* associated devices.
|
||||||
*/
|
*/
|
||||||
void eeh_pe_state_mark(struct eeh_pe *pe, int state)
|
void eeh_pe_state_mark(struct eeh_pe *root, int state)
|
||||||
{
|
{
|
||||||
eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
|
struct eeh_pe *pe;
|
||||||
|
|
||||||
|
eeh_for_each_pe(root, pe)
|
||||||
|
if (!(pe->state & EEH_PE_REMOVED))
|
||||||
|
pe->state |= state;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(eeh_pe_state_mark);
|
EXPORT_SYMBOL_GPL(eeh_pe_state_mark);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eeh_pe_mark_isolated
|
||||||
|
* @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_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);
|
||||||
|
if (pdev)
|
||||||
|
pdev->error_state = pci_channel_io_frozen;
|
||||||
|
}
|
||||||
|
/* Block PCI config access if required */
|
||||||
|
if (pe->state & EEH_PE_CFG_RESTRICTED)
|
||||||
|
pe->state |= EEH_PE_CFG_BLOCKED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
int mode = *((int *)flag);
|
int mode = *((int *)flag);
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue