summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/sun4/io/px/px.c10
-rw-r--r--usr/src/uts/sun4/io/px/px_lib.h6
-rw-r--r--usr/src/uts/sun4/io/px/px_pci.c11
-rw-r--r--usr/src/uts/sun4/io/px/px_var.h4
-rw-r--r--usr/src/uts/sun4u/io/px/px_err.c27
-rw-r--r--usr/src/uts/sun4u/io/px/px_lib4u.c122
-rw-r--r--usr/src/uts/sun4v/io/px/px_lib4v.c14
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)
+{
+}