/* * power management related initialization specific to px * called by px_attach() */ static int px_pwr_setup(dev_info_t *dip) { pcie_pwr_t *pwr_p; int instance = ddi_get_instance(dip); px_t *px_p = INST_TO_STATE(instance); ddi_intr_handle_impl_t hdl; ASSERT(PCIE_PMINFO(dip)); pwr_p = PCIE_NEXUS_PMINFO(dip); ASSERT(pwr_p); /* * indicate support LDI (Layered Driver Interface) * Create the property, if it is not already there */ if (!ddi_prop_exists(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, DDI_KERNEL_IOCTL)) { if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, DDI_KERNEL_IOCTL, NULL, 0) != DDI_PROP_SUCCESS) { DBG(DBG_PWR, dip, "can't create kernel ioctl prop\n"); return (DDI_FAILURE); } } /* No support for device PM. We are always at full power */ pwr_p->pwr_func_lvl = PM_LEVEL_D0; mutex_init(&px_p->px_l23ready_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(px_pwr_pil)); cv_init(&px_p->px_l23ready_cv, NULL, CV_DRIVER, NULL); /* Initialize handle */ bzero(&hdl, sizeof (ddi_intr_handle_impl_t)); hdl.ih_cb_arg1 = px_p; hdl.ih_ver = DDI_INTR_VERSION; hdl.ih_state = DDI_IHDL_STATE_ALLOC; hdl.ih_dip = dip; hdl.ih_pri = px_pwr_pil; /* Add PME_TO_ACK message handler */ hdl.ih_cb_func = (ddi_intr_handler_t *)px_pmeq_intr; if (px_add_msiq_intr(dip, dip, &hdl, MSG_REC, (msgcode_t)PCIE_PME_ACK_MSG, -1, &px_p->px_pm_msiq_id) != DDI_SUCCESS) { DBG(DBG_PWR, dip, "px_pwr_setup: couldn't add " " PME_TO_ACK intr\n"); goto pwr_setup_err1; } px_lib_msg_setmsiq(dip, PCIE_PME_ACK_MSG, px_p->px_pm_msiq_id); px_lib_msg_setvalid(dip, PCIE_PME_ACK_MSG, PCIE_MSG_VALID); if (px_ib_update_intr_state(px_p, px_p->px_dip, hdl.ih_inum, px_msiqid_to_devino(px_p, px_p->px_pm_msiq_id), px_pwr_pil, PX_INTR_STATE_ENABLE, MSG_REC, PCIE_PME_ACK_MSG) != DDI_SUCCESS) { DBG(DBG_PWR, dip, "px_pwr_setup: PME_TO_ACK update interrupt" " state failed\n"); goto px_pwrsetup_err_state; } return (DDI_SUCCESS); px_pwrsetup_err_state: px_lib_msg_setvalid(dip, PCIE_PME_ACK_MSG, PCIE_MSG_INVALID); (void) px_rem_msiq_intr(dip, dip, &hdl, MSG_REC, PCIE_PME_ACK_MSG, px_p->px_pm_msiq_id); pwr_setup_err1: mutex_destroy(&px_p->px_l23ready_lock); cv_destroy(&px_p->px_l23ready_cv); return (DDI_FAILURE); }
/* * pec_msg_add_intr: * * Add interrupt handlers to process correctable/fatal/non fatal * PCIE messages. */ static int px_pec_msg_add_intr(px_t *px_p) { dev_info_t *dip = px_p->px_dip; px_pec_t *pec_p = px_p->px_pec_p; ddi_intr_handle_impl_t hdl; int ret = DDI_SUCCESS; DBG(DBG_MSG, px_p->px_dip, "px_pec_msg_add_intr\n"); /* Initialize handle */ bzero(&hdl, sizeof (ddi_intr_handle_impl_t)); hdl.ih_cb_func = (ddi_intr_handler_t *)px_err_fabric_intr; hdl.ih_ver = DDI_INTR_VERSION; hdl.ih_state = DDI_IHDL_STATE_ALLOC; hdl.ih_dip = dip; /* Add correctable error message handler */ hdl.ih_pri = PX_ERR_LOW_PIL; if ((ret = px_add_msiq_intr(dip, dip, &hdl, MSG_REC, (msgcode_t)PCIE_CORR_MSG, &pec_p->pec_corr_msg_msiq_id)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_CORR_MSG registration failed\n"); return (DDI_FAILURE); } px_lib_msg_setmsiq(dip, PCIE_CORR_MSG, pec_p->pec_corr_msg_msiq_id); px_lib_msg_setvalid(dip, PCIE_CORR_MSG, PCIE_MSG_VALID); if ((ret = px_ib_update_intr_state(px_p, px_p->px_dip, hdl.ih_inum, px_msiqid_to_devino(px_p, pec_p->pec_corr_msg_msiq_id), PX_INTR_STATE_ENABLE, MSG_REC, PCIE_CORR_MSG)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_CORR_MSG update interrupt state failed\n"); return (DDI_FAILURE); } /* Add non-fatal error message handler */ hdl.ih_pri = PX_ERR_PIL; if ((ret = px_add_msiq_intr(dip, dip, &hdl, MSG_REC, (msgcode_t)PCIE_NONFATAL_MSG, &pec_p->pec_non_fatal_msg_msiq_id)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_NONFATAL_MSG registration failed\n"); return (DDI_FAILURE); } px_lib_msg_setmsiq(dip, PCIE_NONFATAL_MSG, pec_p->pec_non_fatal_msg_msiq_id); px_lib_msg_setvalid(dip, PCIE_NONFATAL_MSG, PCIE_MSG_VALID); if ((ret = px_ib_update_intr_state(px_p, px_p->px_dip, hdl.ih_inum, px_msiqid_to_devino(px_p, pec_p->pec_non_fatal_msg_msiq_id), PX_INTR_STATE_ENABLE, MSG_REC, PCIE_NONFATAL_MSG)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_NONFATAL_MSG update interrupt state failed\n"); return (DDI_FAILURE); } /* Add fatal error message handler */ hdl.ih_pri = PX_ERR_PIL; if ((ret = px_add_msiq_intr(dip, dip, &hdl, MSG_REC, (msgcode_t)PCIE_FATAL_MSG, &pec_p->pec_fatal_msg_msiq_id)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_FATAL_MSG registration failed\n"); return (DDI_FAILURE); } px_lib_msg_setmsiq(dip, PCIE_FATAL_MSG, pec_p->pec_fatal_msg_msiq_id); px_lib_msg_setvalid(dip, PCIE_FATAL_MSG, PCIE_MSG_VALID); if ((ret = px_ib_update_intr_state(px_p, px_p->px_dip, hdl.ih_inum, px_msiqid_to_devino(px_p, pec_p->pec_fatal_msg_msiq_id), PX_INTR_STATE_ENABLE, MSG_REC, PCIE_FATAL_MSG)) != DDI_SUCCESS) { DBG(DBG_MSG, px_p->px_dip, "PCIE_FATAL_MSG update interrupt state failed\n"); return (DDI_FAILURE); } return (ret); }