void pcmu_pbm_create(pcmu_t *pcmu_p) { pcmu_pbm_t *pcbm_p; int len; dev_info_t *dip = pcmu_p->pcmu_dip; /* * Allocate a state structure for the PBM and cross-link it * to its per pci node state structure. */ pcbm_p = (pcmu_pbm_t *)kmem_zalloc(sizeof (pcmu_pbm_t), KM_SLEEP); pcmu_p->pcmu_pcbm_p = pcbm_p; pcbm_p->pcbm_pcmu_p = pcmu_p; len = snprintf(pcbm_p->pcbm_nameinst_str, sizeof (pcbm_p->pcbm_nameinst_str), "%s%d", NAMEINST(dip)); pcbm_p->pcbm_nameaddr_str = pcbm_p->pcbm_nameinst_str + ++len; (void) snprintf(pcbm_p->pcbm_nameaddr_str, sizeof (pcbm_p->pcbm_nameinst_str) - len, "%s@%s", NAMEADDR(dip)); pcmu_pbm_setup(pcbm_p); PCMU_DBG4(PCMU_DBG_ATTACH, dip, "pcmu_pbm_create: ctrl=%x, afsr=%x, afar=%x, diag=%x\n", pcbm_p->pcbm_ctrl_reg, pcbm_p->pcbm_async_flt_status_reg, pcbm_p->pcbm_async_flt_addr_reg, pcbm_p->pcbm_diag_reg); PCMU_DBG1(PCMU_DBG_ATTACH, dip, "pcmu_pbm_create: conf=%x\n", pcbm_p->pcbm_config_header); /* * Register a function to disable pbm error interrupts during a panic. */ bus_func_register(BF_TYPE_ERRDIS, (busfunc_t)pcmu_pbm_disable_errors, pcbm_p); /* * create the interrupt-priorities property if it doesn't * already exist to provide a hint as to the PIL level for * our interrupt. */ if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "interrupt-priorities", &len) != DDI_PROP_SUCCESS) { /* Create the interrupt-priorities property. */ (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, "interrupt-priorities", (caddr_t)pcmu_pil, sizeof (pcmu_pil)); } pcmu_pbm_configure(pcbm_p); }
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); }