Ejemplo n.º 1
0
static int
px_enable_err_intr(px_t *px_p)
{
	/* Add FMA Callback handler for failed PIO Loads */
	px_fm_cb_enable(px_p);

	/* Add Common Block mondo handler */
	if (px_cb_add_intr(&px_p->px_cb_fault) != DDI_SUCCESS)
		goto cb_bad;

	/* Add PEU Block Mondo Handler */
	if (px_err_add_intr(&px_p->px_fault) != DDI_SUCCESS)
		goto peu_bad;

	/* Enable interrupt handler for PCIE Fabric Error Messages */
	if (px_pec_msg_add_intr(px_p) != DDI_SUCCESS)
		goto msg_bad;

	return (DDI_SUCCESS);

msg_bad:
	px_err_rem_intr(&px_p->px_fault);
peu_bad:
	px_cb_rem_intr(&px_p->px_cb_fault);
cb_bad:
	px_fm_cb_disable(px_p);

	return (DDI_FAILURE);
}
Ejemplo n.º 2
0
int
px_pec_attach(px_t *px_p)
{
	px_pec_t *pec_p;
	int i, len;
	int nrange = px_p->px_ranges_length / sizeof (px_ranges_t);
	dev_info_t *dip = px_p->px_dip;
	px_ranges_t *rangep = px_p->px_ranges_p;
	int ret;

	/*
	 * Allocate a state structure for the PEC and cross-link it
	 * to its per px node state structure.
	 */
	pec_p = kmem_zalloc(sizeof (px_pec_t), KM_SLEEP);
	px_p->px_pec_p = pec_p;
	pec_p->pec_px_p = px_p;

	len = snprintf(pec_p->pec_nameinst_str,
		sizeof (pec_p->pec_nameinst_str),
		"%s%d", NAMEINST(dip));
	pec_p->pec_nameaddr_str = pec_p->pec_nameinst_str + ++len;
	(void) snprintf(pec_p->pec_nameaddr_str,
		sizeof (pec_p->pec_nameinst_str) - len,
		"%s@%s", NAMEADDR(dip));

	/*
	 * Add interrupt handlers to process correctable/fatal/non fatal
	 * PCIE messages.
	 */
	if ((ret = px_pec_msg_add_intr(px_p)) != DDI_SUCCESS) {
		px_pec_msg_rem_intr(px_p);
		return (ret);
	}

	/*
	 * Get this pec's mem32 and mem64 segments to determine whether
	 * a dma object originates from ths pec. i.e. dev to dev dma
	 */
	for (i = 0; i < nrange; i++, rangep++) {
		uint64_t rng_addr, rng_size, *pfnbp, *pfnlp;
		uint32_t rng_type = rangep->child_high & PCI_ADDR_MASK;

		switch (rng_type) {
			case PCI_ADDR_MEM32:
				pfnbp = &pec_p->pec_base32_pfn;
				pfnlp = &pec_p->pec_last32_pfn;
				break;

			case PCI_ADDR_MEM64:
				pfnbp = &pec_p->pec_base64_pfn;
				pfnlp = &pec_p->pec_last64_pfn;
				break;

			case PCI_ADDR_CONFIG:
			case PCI_ADDR_IO:
			default:
				continue;
		}
		rng_addr = (uint64_t)(rangep->parent_high &
					px_ranges_phi_mask) << 32;
		rng_addr |= (uint64_t)rangep->parent_low;
		rng_size = (uint64_t)rangep->size_high << 32;
		rng_size |= (uint64_t)rangep->size_low;

		*pfnbp = mmu_btop(rng_addr);
		*pfnlp = mmu_btop(rng_addr + rng_size);
	}

	mutex_init(&pec_p->pec_pokefault_mutex, NULL, MUTEX_DRIVER,
	    (void *)px_p->px_fm_ibc);

	return (DDI_SUCCESS);
}