powerpc/powernv: Only clear EEH freeze for some errors

Only clear an EEH freeze if an error occurs.  However, if an OPAL_HARDWARE
error is returned, this indicates a hardware failure which cannot be
unfrozen, and instead needs a hardware reset.  Attempting to unfreeze a
broken PCH will result in console spam for each attempt.  To avoid the spam,
just don't do it.
This commit is contained in:
Justin Hibbits 2019-08-01 03:59:25 +00:00
parent be01018809
commit 0effb2ccf3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=350494
2 changed files with 27 additions and 6 deletions

View file

@ -53,6 +53,7 @@ int opal_call(uint64_t token, ...);
#define OPAL_PCI_CONFIG_WRITE_BYTE 16
#define OPAL_PCI_CONFIG_WRITE_HALF_WORD 17
#define OPAL_PCI_CONFIG_WRITE_WORD 18
#define OPAL_PCI_EEH_FREEZE_STATUS 23
#define OPAL_PCI_EEH_FREEZE_CLEAR 26
#define OPAL_PCI_PHB_MMIO_ENABLE 27
#define OPAL_PCI_SET_PHB_MEM_WINDOW 28

View file

@ -117,6 +117,8 @@ static bus_dma_tag_t opalpci_get_dma_tag(device_t dev, device_t child);
#define OPAL_EEH_ACTION_CLEAR_FREEZE_DMA 2
#define OPAL_EEH_ACTION_CLEAR_FREEZE_ALL 3
#define OPAL_EEH_STOPPED_NOT_FROZEN 0
/*
* Constants
*/
@ -501,10 +503,11 @@ opalpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
{
struct opalpci_softc *sc;
uint64_t config_addr;
uint8_t byte;
uint8_t byte, eeh_state;
uint16_t half;
uint32_t word;
int error;
uint16_t err_type;
sc = device_get_softc(dev);
@ -536,11 +539,19 @@ opalpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
*
* XXX: Make this conditional on the existence of a freeze
*/
opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, OPAL_PCI_DEFAULT_PE,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
if (error != OPAL_SUCCESS)
if (error != OPAL_SUCCESS) {
if (error != OPAL_HARDWARE) {
opal_call(OPAL_PCI_EEH_FREEZE_STATUS, sc->phb_id,
OPAL_PCI_DEFAULT_PE, vtophys(&eeh_state),
vtophys(&err_type), NULL);
if (eeh_state != OPAL_EEH_STOPPED_NOT_FROZEN)
opal_call(OPAL_PCI_EEH_FREEZE_CLEAR,
sc->phb_id, OPAL_PCI_DEFAULT_PE,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
}
word = 0xffffffff;
}
return (word);
}
@ -552,6 +563,8 @@ opalpci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
struct opalpci_softc *sc;
uint64_t config_addr;
int error = OPAL_SUCCESS;
uint16_t err_type;
uint8_t eeh_state;
sc = device_get_softc(dev);
@ -577,8 +590,15 @@ opalpci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
* Poking config state for non-existant devices can make
* the host bridge hang up. Clear any errors.
*/
opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id,
OPAL_PCI_DEFAULT_PE, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
if (error != OPAL_HARDWARE) {
opal_call(OPAL_PCI_EEH_FREEZE_STATUS, sc->phb_id,
OPAL_PCI_DEFAULT_PE, vtophys(&eeh_state),
vtophys(&err_type), NULL);
if (eeh_state != OPAL_EEH_STOPPED_NOT_FROZEN)
opal_call(OPAL_PCI_EEH_FREEZE_CLEAR,
sc->phb_id, OPAL_PCI_DEFAULT_PE,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
}
}
}