diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/sun4/io/px/px.c | 10 | ||||
-rw-r--r-- | usr/src/uts/sun4/io/px/px_lib.h | 6 | ||||
-rw-r--r-- | usr/src/uts/sun4/io/px/px_pci.c | 11 | ||||
-rw-r--r-- | usr/src/uts/sun4/io/px/px_var.h | 4 | ||||
-rw-r--r-- | usr/src/uts/sun4u/io/px/px_err.c | 27 | ||||
-rw-r--r-- | usr/src/uts/sun4u/io/px/px_lib4u.c | 122 | ||||
-rw-r--r-- | usr/src/uts/sun4v/io/px/px_lib4v.c | 14 |
7 files changed, 180 insertions, 14 deletions
diff --git a/usr/src/uts/sun4/io/px/px.c b/usr/src/uts/sun4/io/px/px.c index 8d1bdd60a4..78cd5f6512 100644 --- a/usr/src/uts/sun4/io/px/px.c +++ b/usr/src/uts/sun4/io/px/px.c @@ -314,6 +314,11 @@ px_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) pwr_common_teardown(dip); } + /* + * add cpr callback + */ + px_cpr_add_callb(px_p); + ddi_report_dev(dip); px_p->px_state = PX_ATTACHED; @@ -403,6 +408,11 @@ px_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) case DDI_DETACH: DBG(DBG_DETACH, dip, "DDI_DETACH\n"); + /* + * remove cpr callback + */ + px_cpr_rem_callb(px_p); + #ifdef HOTPLUG /* * Hot plug will be done later. diff --git a/usr/src/uts/sun4/io/px/px_lib.h b/usr/src/uts/sun4/io/px/px_lib.h index 3b3f729578..1921c34507 100644 --- a/usr/src/uts/sun4/io/px/px_lib.h +++ b/usr/src/uts/sun4/io/px/px_lib.h @@ -204,6 +204,12 @@ extern uint32_t px_fab_get(px_t *px_p, pcie_req_id_t bdf, extern void px_fab_set(px_t *px_p, pcie_req_id_t bdf, uint16_t offset, uint32_t val); +/* + * CPR callback + */ +extern void px_cpr_add_callb(px_t *); +extern void px_cpr_rem_callb(px_t *); + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/sun4/io/px/px_pci.c b/usr/src/uts/sun4/io/px/px_pci.c index 0693a2efa2..e6ce904050 100644 --- a/usr/src/uts/sun4/io/px/px_pci.c +++ b/usr/src/uts/sun4/io/px/px_pci.c @@ -270,7 +270,14 @@ pxb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) ddi_get_soft_state(pxb_state, instance); (void) pcie_pwr_resume(devi); + DEVI_SET_ATTACHING(devi); + if (pxb_fm_init(pxb) != DDI_SUCCESS) + cmn_err(CE_WARN, "px_pci: dip0x%p failed pxb_fm_init " + "at resume\n", devi); + DEVI_CLR_ATTACHING(devi); + return (DDI_SUCCESS); + case DDI_ATTACH: DBG(DBG_ATTACH, devi, "DDI_ATTACH\n"); @@ -460,6 +467,10 @@ pxb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) pxb = (pxb_devstate_t *) ddi_get_soft_state(pxb_state, ddi_get_instance(devi)); + DEVI_SET_DETACHING(devi); + pxb_fm_fini(pxb); + DEVI_CLR_DETACHING(devi); + error = pcie_pwr_suspend(devi); return (error); diff --git a/usr/src/uts/sun4/io/px/px_var.h b/usr/src/uts/sun4/io/px/px_var.h index efde9b22ef..2cdd100e38 100644 --- a/usr/src/uts/sun4/io/px/px_var.h +++ b/usr/src/uts/sun4/io/px/px_var.h @@ -29,6 +29,8 @@ #pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/callb.h> + #ifdef __cplusplus extern "C" { #endif @@ -149,6 +151,8 @@ struct px { uint32_t px_pme_ignored; /* count of PME ignored */ uint32_t px_lup_ignored; /* count of link up events ignored */ + /* CPR callback id */ + callb_id_t px_cprcb_id; }; /* px soft state flag */ diff --git a/usr/src/uts/sun4u/io/px/px_err.c b/usr/src/uts/sun4u/io/px/px_err.c index 5ecfde0d50..90c19aaf69 100644 --- a/usr/src/uts/sun4u/io/px/px_err.c +++ b/usr/src/uts/sun4u/io/px/px_err.c @@ -426,12 +426,12 @@ px_err_bit_desc_t px_err_lpug_tbl[] = { */ px_err_reg_desc_t px_err_reg_tbl[] = { { MnT6(cb), R4(JBC), "JBC Error"}, - { MnT6(mmu), R4(MMU), "IMU Error"}, - { MnT6(imu), R4(IMU), "ILU Error"}, + { MnT6(mmu), R4(MMU), "MMU Error"}, + { MnT6(imu), R4(IMU), "IMU Error"}, { MnT6(tlu_ue), TR4(UNCORRECTABLE_ERROR), "TLU UE"}, { MnT6(tlu_ce), TR4(CORRECTABLE_ERROR), "TLU CE"}, { MnT6(tlu_oe), TR4(OTHER_EVENT), "TLU OE"}, - { MnT6(ilu), R4(ILU), "MMU Error"}, + { MnT6(ilu), R4(ILU), "ILU Error"}, { MnT6(lpul), LR4(LINK_LAYER), "LPU Link Layer"}, { MnT6(lpup), LR4_FIXME(PHY), "LPU Phy Layer"}, { MnT6(lpur), LR4(RECEIVE_PHY), "LPU RX Phy Layer"}, @@ -1314,18 +1314,17 @@ px_err_imu_rbne_handle(dev_info_t *rpdip, caddr_t csr_base, imu_log_enable = CSR_XR(csr_base, err_reg_descr->log_addr); imu_intr_enable = CSR_XR(csr_base, err_reg_descr->enable_addr); - if (imu_log_enable & imu_intr_enable & mask) { + /* + * If matching bit is not set, meaning corresponding rbne not + * enabled, then receiving it indicates some sort of malfunction + * possibly in hardware. + * + * Other wise, software may have intentionally disabled certain + * errors for a period of time within which the occuring of the + * disabled errors become rbne, that is non fatal. + */ + if (!(imu_log_enable & imu_intr_enable & mask)) err = PX_FATAL_SW; - } else { - /* - * S/W bug - this error should always be enabled - */ - - /* enable error & intr reporting for this bit */ - CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, imu_log_enable | mask); - CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, imu_intr_enable | mask); - err = PX_NONFATAL; - } return (err); } diff --git a/usr/src/uts/sun4u/io/px/px_lib4u.c b/usr/src/uts/sun4u/io/px/px_lib4u.c index 5443bce1c1..1ea33463d2 100644 --- a/usr/src/uts/sun4u/io/px/px_lib4u.c +++ b/usr/src/uts/sun4u/io/px/px_lib4u.c @@ -63,6 +63,7 @@ static int px_goto_l0(px_t *px_p); static int px_pre_pwron_check(px_t *px_p); static uint32_t px_identity_chip(px_t *px_p); static void px_lib_clr_errs(px_t *px_p, px_pec_t *pec_p); +static boolean_t px_cpr_callb(void *arg, int code); /* * px_lib_map_registers @@ -2006,3 +2007,124 @@ px_fab_set(px_t *px_p, pcie_req_id_t bdf, uint16_t offset, stphysio(base_addr, LE_32(val)); } + +/* + * cpr callback + * + * disable fabric error msg interrupt prior to suspending + * all device drivers; re-enable fabric error msg interrupt + * after all devices are resumed. + */ +static boolean_t +px_cpr_callb(void *arg, int code) +{ + px_t *px_p = (px_t *)arg; + px_ib_t *ib_p = px_p->px_ib_p; + px_pec_t *pec_p = px_p->px_pec_p; + pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; + caddr_t csr_base; + devino_t ce_ino, nf_ino, f_ino; + px_ib_ino_info_t *ce_ino_p, *nf_ino_p, *f_ino_p; + uint64_t imu_log_enable, imu_intr_enable; + uint64_t imu_log_mask, imu_intr_mask; + + ce_ino = px_msiqid_to_devino(px_p, pec_p->pec_corr_msg_msiq_id); + nf_ino = px_msiqid_to_devino(px_p, pec_p->pec_non_fatal_msg_msiq_id); + f_ino = px_msiqid_to_devino(px_p, pec_p->pec_fatal_msg_msiq_id); + csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; + + imu_log_enable = CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE); + imu_intr_enable = CSR_XR(csr_base, IMU_INTERRUPT_ENABLE); + + imu_log_mask = BITMASK(IMU_ERROR_LOG_ENABLE_FATAL_MES_NOT_EN_LOG_EN) | + BITMASK(IMU_ERROR_LOG_ENABLE_NONFATAL_MES_NOT_EN_LOG_EN) | + BITMASK(IMU_ERROR_LOG_ENABLE_COR_MES_NOT_EN_LOG_EN); + + imu_intr_mask = + BITMASK(IMU_INTERRUPT_ENABLE_FATAL_MES_NOT_EN_S_INT_EN) | + BITMASK(IMU_INTERRUPT_ENABLE_NONFATAL_MES_NOT_EN_S_INT_EN) | + BITMASK(IMU_INTERRUPT_ENABLE_COR_MES_NOT_EN_S_INT_EN) | + BITMASK(IMU_INTERRUPT_ENABLE_FATAL_MES_NOT_EN_P_INT_EN) | + BITMASK(IMU_INTERRUPT_ENABLE_NONFATAL_MES_NOT_EN_P_INT_EN) | + BITMASK(IMU_INTERRUPT_ENABLE_COR_MES_NOT_EN_P_INT_EN); + + switch (code) { + case CB_CODE_CPR_CHKPT: + /* disable imu rbne on corr/nonfatal/fatal errors */ + CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, + imu_log_enable & (~imu_log_mask)); + + CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, + imu_intr_enable & (~imu_intr_mask)); + + /* disable CORR intr mapping */ + px_ib_intr_disable(ib_p, ce_ino, IB_INTR_NOWAIT); + + /* disable NON FATAL intr mapping */ + px_ib_intr_disable(ib_p, nf_ino, IB_INTR_NOWAIT); + + /* disable FATAL intr mapping */ + px_ib_intr_disable(ib_p, f_ino, IB_INTR_NOWAIT); + + break; + + case CB_CODE_CPR_RESUME: + mutex_enter(&ib_p->ib_ino_lst_mutex); + + ce_ino_p = px_ib_locate_ino(ib_p, ce_ino); + nf_ino_p = px_ib_locate_ino(ib_p, nf_ino); + f_ino_p = px_ib_locate_ino(ib_p, f_ino); + + /* enable CORR intr mapping */ + if (ce_ino_p) + px_ib_intr_enable(px_p, ce_ino_p->ino_cpuid, ce_ino); + else + cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " + "reenable PCIe Correctable msg intr.\n"); + + /* enable NON FATAL intr mapping */ + if (nf_ino_p) + px_ib_intr_enable(px_p, nf_ino_p->ino_cpuid, nf_ino); + else + cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " + "reenable PCIe Non Fatal msg intr.\n"); + + /* enable FATAL intr mapping */ + if (f_ino_p) + px_ib_intr_enable(px_p, f_ino_p->ino_cpuid, f_ino); + else + cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " + "reenable PCIe Fatal msg intr.\n"); + + mutex_exit(&ib_p->ib_ino_lst_mutex); + + /* enable corr/nonfatal/fatal not enable error */ + CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, (imu_log_enable | + (imu_log_mask & px_imu_log_mask))); + CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, (imu_intr_enable | + (imu_intr_mask & px_imu_intr_mask))); + + break; + } + + return (B_TRUE); +} + +/* + * add cpr callback + */ +void +px_cpr_add_callb(px_t *px_p) +{ + px_p->px_cprcb_id = callb_add(px_cpr_callb, (void *)px_p, + CB_CL_CPR_POST_USER, "px_cpr"); +} + +/* + * remove cpr callback + */ +void +px_cpr_rem_callb(px_t *px_p) +{ + (void) callb_delete(px_p->px_cprcb_id); +} diff --git a/usr/src/uts/sun4v/io/px/px_lib4v.c b/usr/src/uts/sun4v/io/px/px_lib4v.c index 7543bbf5da..8bb03b3fdc 100644 --- a/usr/src/uts/sun4v/io/px/px_lib4v.c +++ b/usr/src/uts/sun4v/io/px/px_lib4v.c @@ -1840,3 +1840,17 @@ px_fab_set(px_t *px_p, pcie_req_id_t bdf, uint16_t offset, (void) hvio_config_put(px_p->px_dev_hdl, (bdf << PX_RA_BDF_SHIFT), offset, 4, wdata); } + +/* Dummy cpr add callback */ +/*ARGSUSED*/ +void +px_cpr_add_callb(px_t *px_p) +{ +} + +/* Dummy cpr rem callback */ +/*ARGSUSED*/ +void +px_cpr_rem_callb(px_t *px_p) +{ +} |