Пример #1
0
/*
 * px_pec_msg_rem_intr:
 *
 * Remove interrupt handlers to process correctable/fatal/non fatal
 * PCIE messages. For now, all these PCIe messages are mapped to
 * same MSIQ.
 */
static void
px_pec_msg_rem_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;

	DBG(DBG_MSG, px_p->px_dip, "px_pec_msg_rem_intr: dip 0x%p\n", dip);

	/* Initialize handle */
	bzero(&hdl, sizeof (ddi_intr_handle_impl_t));
	hdl.ih_ver = DDI_INTR_VERSION;
	hdl.ih_state = DDI_IHDL_STATE_ALLOC;
	hdl.ih_dip = dip;

	if (pec_p->pec_corr_msg_msiq_id >= 0) {
		px_lib_msg_setvalid(dip, PCIE_CORR_MSG, PCIE_MSG_INVALID);

		(void) px_rem_msiq_intr(dip, dip, &hdl, MSG_REC,
		    PCIE_CORR_MSG, pec_p->pec_corr_msg_msiq_id);

		(void) 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_DISABLE, MSG_REC, PCIE_CORR_MSG);

		pec_p->pec_corr_msg_msiq_id = -1;
	}

	if (pec_p->pec_non_fatal_msg_msiq_id >= 0) {
		px_lib_msg_setvalid(dip, PCIE_NONFATAL_MSG,
		    PCIE_MSG_INVALID);

		(void) px_rem_msiq_intr(dip, dip, &hdl, MSG_REC,
		    PCIE_NONFATAL_MSG, pec_p->pec_non_fatal_msg_msiq_id);

		(void) 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_DISABLE, MSG_REC, PCIE_NONFATAL_MSG);

		pec_p->pec_non_fatal_msg_msiq_id = -1;
	}

	if (pec_p->pec_fatal_msg_msiq_id >= 0) {
		px_lib_msg_setvalid(dip, PCIE_FATAL_MSG, PCIE_MSG_INVALID);

		(void) px_rem_msiq_intr(dip, dip, &hdl, MSG_REC,
		    PCIE_FATAL_MSG, pec_p->pec_fatal_msg_msiq_id);

		(void) 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_DISABLE, MSG_REC, PCIE_FATAL_MSG);

		pec_p->pec_fatal_msg_msiq_id = -1;
	}
}
Пример #2
0
/*
 * undo whatever is done in px_pwr_setup. called by px_detach()
 */
static void
px_pwr_teardown(dev_info_t *dip)
{
	int instance = ddi_get_instance(dip);
	px_t *px_p = INST_TO_STATE(instance);
	ddi_intr_handle_impl_t	hdl;

	if (!PCIE_PMINFO(dip) || !PCIE_NEXUS_PMINFO(dip))
		return;

	/* Initialize handle */
	bzero(&hdl, sizeof (ddi_intr_handle_impl_t));
	hdl.ih_ver = DDI_INTR_VERSION;
	hdl.ih_state = DDI_IHDL_STATE_ALLOC;
	hdl.ih_dip = dip;
	hdl.ih_pri = px_pwr_pil;

	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);

	(void) 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_DISABLE, MSG_REC, PCIE_PME_ACK_MSG);

	px_p->px_pm_msiq_id = (msiqid_t)-1;

	cv_destroy(&px_p->px_l23ready_cv);
	mutex_destroy(&px_p->px_l23ready_lock);
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
/*
 * 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);
}