static void rge_chip_poke_cfg(rge_t *rgep, rge_peekpoke_t *ppd) { uint64_t regval; uint64_t regno; RGE_TRACE(("rge_chip_poke_cfg($%p, $%p)", (void *)rgep, (void *)ppd)); regno = ppd->pp_acc_offset; regval = ppd->pp_acc_data; switch (ppd->pp_acc_size) { case 1: pci_config_put8(rgep->cfg_handle, regno, regval); break; case 2: pci_config_put16(rgep->cfg_handle, regno, regval); break; case 4: pci_config_put32(rgep->cfg_handle, regno, regval); break; case 8: pci_config_put64(rgep->cfg_handle, regno, regval); break; } }
void rge_chip_cfg_init(rge_t *rgep, chip_id_t *cidp) { ddi_acc_handle_t handle; uint16_t commd; handle = rgep->cfg_handle; /* * Save PCI cache line size and subsystem vendor ID */ cidp->command = pci_config_get16(handle, PCI_CONF_COMM); cidp->vendor = pci_config_get16(handle, PCI_CONF_VENID); cidp->device = pci_config_get16(handle, PCI_CONF_DEVID); cidp->subven = pci_config_get16(handle, PCI_CONF_SUBVENID); cidp->subdev = pci_config_get16(handle, PCI_CONF_SUBSYSID); cidp->revision = pci_config_get8(handle, PCI_CONF_REVID); cidp->clsize = pci_config_get8(handle, PCI_CONF_CACHE_LINESZ); cidp->latency = pci_config_get8(handle, PCI_CONF_LATENCY_TIMER); /* * Turn on Master Enable (DMA) and IO Enable bits. * Enable PCI Memory Space accesses */ commd = cidp->command; commd |= PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO; pci_config_put16(handle, PCI_CONF_COMM, commd); RGE_DEBUG(("rge_chip_cfg_init: vendor 0x%x device 0x%x revision 0x%x", cidp->vendor, cidp->device, cidp->revision)); RGE_DEBUG(("rge_chip_cfg_init: subven 0x%x subdev 0x%x", cidp->subven, cidp->subdev)); RGE_DEBUG(("rge_chip_cfg_init: clsize %d latency %d command 0x%x", cidp->clsize, cidp->latency, cidp->command)); }
/* * audio1575_pci_enable() * * Description: * This routine Enables all PCI IO and MEMORY accesses * * Arguments: * audio1575_state_t *statep The device's state structure */ static void audio1575_pci_enable(audio1575_state_t *statep) { uint16_t pcics_reg; pcics_reg = pci_config_get16(statep->pcih, PCI_CONF_COMM); pcics_reg |= (PCI_COMM_IO | PCI_COMM_MAE | PCI_COMM_ME); pci_config_put16(statep->pcih, PCI_CONF_COMM, pcics_reg); }
/* * audio1575_pci_disable() * * Description: * This routine Disables all PCI IO and MEMORY accesses * * Arguments: * audio1575_state_t *statep The device's state structure */ static void audio1575_pci_disable(audio1575_state_t *statep) { uint16_t pcics_reg; if (statep->pcih == NULL) return; pcics_reg = pci_config_get16(statep->pcih, PCI_CONF_COMM); pcics_reg &= ~(PCI_COMM_IO | PCI_COMM_MAE | PCI_COMM_ME); pci_config_put16(statep->pcih, PCI_CONF_COMM, pcics_reg); }
static void agp_target_set_gartaddr(agp_target_softstate_t *softstate, uint32_t gartaddr) { ASSERT(softstate->tsoft_acaptr); /* Disable the GTLB for Intel chipsets */ pci_config_put16(softstate->tsoft_pcihdl, softstate->tsoft_acaptr + AGP_CONF_CONTROL, 0x0000); pci_config_put32(softstate->tsoft_pcihdl, softstate->tsoft_acaptr + AGP_CONF_ATTBASE, gartaddr & AGP_ATTBASE_MASK); }
int npe_enable_htmsi(ddi_acc_handle_t cfg_hdl) { uint16_t ptr; uint16_t reg; if (pci_htcap_locate(cfg_hdl, PCI_HTCAP_TYPE_MASK, PCI_HTCAP_MSIMAP_TYPE, &ptr) != DDI_SUCCESS) return (DDI_FAILURE); reg = pci_config_get16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF); reg |= PCI_HTCAP_MSIMAP_ENABLE; pci_config_put16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF, reg); return (DDI_SUCCESS); }
/* * Enable reporting of AER capability next pointer. * This needs to be done only for CK8-04 devices * by setting NV_XVR_VEND_CYA1 (offset 0xf40) bit 13 * NOTE: BIOS is disabling this, it needs to be enabled temporarily */ void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl) { ushort_t cya1; if ((pci_config_get16(cfg_hdl, PCI_CONF_VENID) == NVIDIA_VENDOR_ID) && (pci_config_get16(cfg_hdl, PCI_CONF_DEVID) == NVIDIA_CK804_DEVICE_ID) && (pci_config_get8(cfg_hdl, PCI_CONF_REVID) >= NVIDIA_CK804_AER_VALID_REVID)) { cya1 = pci_config_get16(cfg_hdl, NVIDIA_CK804_VEND_CYA1_OFF); if (!(cya1 & ~NVIDIA_CK804_VEND_CYA1_ERPT_MASK)) (void) pci_config_put16(cfg_hdl, NVIDIA_CK804_VEND_CYA1_OFF, cya1 | NVIDIA_CK804_VEND_CYA1_ERPT_VAL); } }
/* * Write the given 16-bit value to pci-e config space at offset reg into the * pci-e capability block. Note that this refers to the pci-e capability block * in standard pci config space, not the block in pci-e extended config space. */ int32_t e1000_write_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) { uint8_t pcie_id = PCI_CAP_ID_PCI_E; uint16_t pcie_cap; int32_t status; /* locate the pci-e capability block */ status = pci_lcap_locate(OS_DEP(hw)->cfg_handle, pcie_id, &pcie_cap); if (status == DDI_SUCCESS) { /* write at given offset into block */ pci_config_put16(OS_DEP(hw)->cfg_handle, (off_t)(pcie_cap + reg), *value); } return (status); }
/* * ppb_restore_config_regs * * This routine restores the state of the configuration registers of all * the child nodes of each PBM. * * used by: ppb_attach() on resume * * return value: none */ static void ppb_restore_config_regs(ppb_devstate_t *ppb_p) { int i; dev_info_t *dip; ddi_acc_handle_t config_handle; for (i = 0; i < ppb_p->config_state_index; i++) { dip = ppb_p->config_state[i].dip; if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: can't config space for %s%d\n", ddi_driver_name(ppb_p->dip), ddi_get_instance(ppb_p->dip), ddi_driver_name(dip), ddi_get_instance(dip)); continue; } pci_config_put16(config_handle, PCI_CONF_COMM, ppb_p->config_state[i].command); pci_config_teardown(&config_handle); } }
static int ppb_ht_msimap_set(ddi_acc_handle_t cfg_hdl, int cmd) { uint16_t ptr; uint16_t reg; if (pci_htcap_locate(cfg_hdl, PCI_HTCAP_TYPE_MASK, PCI_HTCAP_MSIMAP_TYPE, &ptr) != DDI_SUCCESS) return (0); reg = pci_config_get16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF); switch (cmd) { case HT_MSIMAP_ENABLE: reg |= PCI_HTCAP_MSIMAP_ENABLE; break; case HT_MSIMAP_DISABLE: default: reg &= ~(uint16_t)PCI_HTCAP_MSIMAP_ENABLE; } pci_config_put16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF, reg); return (1); }
/*ARGSUSED*/ static int agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred, int *rval) { int instance = DEV2INST(dev); agp_target_softstate_t *st; static char kernel_only[] = "amd64_gart_ioctl: is a kernel only ioctl"; if (!(mode & FKIOCTL)) { TARGETDB_PRINT2((CE_CONT, kernel_only)); return (ENXIO); } st = GETSOFTC(instance); if (st == NULL) return (ENXIO); mutex_enter(&st->tsoft_lock); switch (cmd) { case CHIP_DETECT: { int type; switch (st->tsoft_devid & VENDOR_ID_MASK) { case INTEL_VENDOR_ID: type = CHIP_IS_INTEL; break; case AMD_VENDOR_ID: type = CHIP_IS_AMD; break; default: type = 0; } if (ddi_copyout(&type, (void *)data, sizeof (int), mode)) { mutex_exit(&st->tsoft_lock); return (EFAULT); } break; } case I8XX_GET_PREALLOC_SIZE: { size_t prealloc_size; if ((st->tsoft_devid & VENDOR_ID_MASK) != INTEL_VENDOR_ID) { mutex_exit(&st->tsoft_lock); return (EINVAL); } prealloc_size = i8xx_biosmem_detect(st); if (ddi_copyout(&prealloc_size, (void *)data, sizeof (size_t), mode)) { mutex_exit(&st->tsoft_lock); return (EFAULT); } break; } case AGP_TARGET_GETINFO: { i_agp_info_t info; uint32_t value; off_t cap; ASSERT(st->tsoft_acaptr); cap = st->tsoft_acaptr; value = pci_config_get32(st->tsoft_pcihdl, cap); info.iagp_ver.agpv_major = (uint16_t)((value >> 20) & 0xf); info.iagp_ver.agpv_minor = (uint16_t)((value >> 16) & 0xf); info.iagp_devid = st->tsoft_devid; info.iagp_mode = pci_config_get32(st->tsoft_pcihdl, cap + AGP_CONF_STATUS); info.iagp_aperbase = agp_target_get_apbase(st); info.iagp_apersize = agp_target_get_apsize(st); if (ddi_copyout(&info, (void *)data, sizeof (i_agp_info_t), mode)) { mutex_exit(&st->tsoft_lock); return (EFAULT); } break; } /* * This ioctl is only for Intel AGP chipsets. * It is not necessary for the AMD8151 AGP bridge, because * this register in the AMD8151 does not control any hardware. * It is only provided for compatibility with an Intel AGP bridge. * Please refer to the <<AMD8151 data sheet>> page 24, * AGP device GART pointer. */ case AGP_TARGET_SET_GATTADDR: { uint32_t gartaddr; if (ddi_copyin((void *)data, &gartaddr, sizeof (uint32_t), mode)) { mutex_exit(&st->tsoft_lock); return (EFAULT); } agp_target_set_gartaddr(st, gartaddr); break; } case AGP_TARGET_SETCMD: { uint32_t command; if (ddi_copyin((void *)data, &command, sizeof (uint32_t), mode)) { mutex_exit(&st->tsoft_lock); return (EFAULT); } ASSERT(st->tsoft_acaptr); pci_config_put32(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_COMMAND, command); break; } case AGP_TARGET_FLUSH_GTLB: { uint16_t value; ASSERT(st->tsoft_acaptr); value = pci_config_get16(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_CONTROL); value &= ~AGPCTRL_GTLBEN; pci_config_put16(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_CONTROL, value); value |= AGPCTRL_GTLBEN; pci_config_put16(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_CONTROL, value); break; } case AGP_TARGET_CONFIGURE: { uint8_t value; ASSERT(st->tsoft_acaptr); value = pci_config_get8(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_MISC); value |= AGP_MISC_APEN; pci_config_put8(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_MISC, value); break; } case AGP_TARGET_UNCONFIG: { uint32_t value1; uint8_t value2; ASSERT(st->tsoft_acaptr); pci_config_put16(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_CONTROL, 0x0); value2 = pci_config_get8(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_MISC); value2 &= ~AGP_MISC_APEN; pci_config_put8(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_MISC, value2); value1 = pci_config_get32(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_COMMAND); value1 &= ~AGPCMD_AGPEN; pci_config_put32(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_COMMAND, value1); pci_config_put32(st->tsoft_pcihdl, st->tsoft_acaptr + AGP_CONF_ATTBASE, 0x0); break; } default: mutex_exit(&st->tsoft_lock); return (ENXIO); } /* end switch */ mutex_exit(&st->tsoft_lock); return (0); }
void ixgbe_write_pci_cfg(struct ixgbe_hw *hw, uint32_t reg, uint32_t val) { pci_config_put16(OS_DEP(hw)->cfg_handle, reg, val); }
static int ppb_initchild(dev_info_t *child) { char name[MAXNAMELEN]; ddi_acc_handle_t config_handle; ushort_t command_preserve, command; uint_t n; ushort_t bcr; uchar_t header_type; uchar_t min_gnt, latency_timer; ppb_devstate_t *ppb; /* * Name the child */ if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) return (DDI_FAILURE); ddi_set_name_addr(child, name); ddi_set_parent_data(child, NULL); /* * Pseudo nodes indicate a prototype node with per-instance * properties to be merged into the real h/w device node. * The interpretation of the unit-address is DD[,F] * where DD is the device id and F is the function. */ if (ndi_dev_is_persistent_node(child) == 0) { extern int pci_allow_pseudo_children; /* * Try to merge the properties from this prototype * node into real h/w nodes. */ if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) { /* * Merged ok - return failure to remove the node. */ ppb_removechild(child); return (DDI_FAILURE); } /* workaround for ddivs to run under PCI */ if (pci_allow_pseudo_children) return (DDI_SUCCESS); /* * The child was not merged into a h/w node, * but there's not much we can do with it other * than return failure to cause the node to be removed. */ cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", ddi_driver_name(child), ddi_get_name_addr(child), ddi_driver_name(child)); ppb_removechild(child); return (DDI_NOT_WELL_FORMED); } ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state, ddi_get_instance(ddi_get_parent(child))); ddi_set_parent_data(child, NULL); /* * If hardware is PM capable, set up the power info structure. * This also ensures the the bus will not be off (0MHz) otherwise * system panics during a bus access. */ if (PM_CAPABLE(ppb->ppb_pwr_p)) { /* * Create a pwr_info struct for child. Bus will be * at full speed after creating info. */ pci_pwr_create_info(ppb->ppb_pwr_p, child); #ifdef DEBUG ASSERT(ppb->ppb_pwr_p->current_lvl == PM_LEVEL_B0); #endif } /* * If configuration registers were previously saved by * child (before it entered D3), then let the child do the * restore to set up the config regs as it'll first need to * power the device out of D3. */ if (ddi_prop_exists(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "config-regs-saved-by-child") == 1) { DEBUG2(DBG_PWR, ddi_get_parent(child), "INITCHILD: config regs to be restored by child" " for %s@%s\n", ddi_node_name(child), ddi_get_name_addr(child)); return (DDI_SUCCESS); } DEBUG2(DBG_PWR, ddi_get_parent(child), "INITCHILD: config regs setup for %s@%s\n", ddi_node_name(child), ddi_get_name_addr(child)); if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) { if (PM_CAPABLE(ppb->ppb_pwr_p)) { pci_pwr_rm_info(ppb->ppb_pwr_p, child); } return (DDI_FAILURE); } /* * Determine the configuration header type. */ header_type = pci_config_get8(config_handle, PCI_CONF_HEADER); /* * Support for the "command-preserve" property. */ command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "command-preserve", 0); command = pci_config_get16(config_handle, PCI_CONF_COMM); command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); command |= (ppb_command_default & ~command_preserve); pci_config_put16(config_handle, PCI_CONF_COMM, command); /* * If the device has a bus control register then program it * based on the settings in the command register. */ if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL); if (ppb_command_default & PCI_COMM_PARITY_DETECT) bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE; if (ppb_command_default & PCI_COMM_SERR_ENABLE) bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE; bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE; pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr); } /* * Initialize cache-line-size configuration register if needed. */ if (ppb_set_cache_line_size_register && ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "cache-line-size", 0) == 0) { pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ, ppb->ppb_cache_line_size); n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ); if (n != 0) { (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, "cache-line-size", n); } } /* * Initialize latency timer configuration registers if needed. */ if (ppb_set_latency_timer_register && ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "latency-timer", 0) == 0) { if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { latency_timer = ppb->ppb_latency_timer; pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER, ppb->ppb_latency_timer); } else { min_gnt = pci_config_get8(config_handle, PCI_CONF_MIN_G); latency_timer = min_gnt * 8; } pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER, latency_timer); n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER); if (n != 0) { (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, "latency-timer", n); } } /* * SPARC PCIe FMA specific * * Note: parent_data for parent is created only if this is sparc PCI-E * platform, for which, SG take a different route to handle device * errors. */ if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) { if (pcie_init_cfghdl(child) != DDI_SUCCESS) { pci_config_teardown(&config_handle); return (DDI_FAILURE); } pcie_init_dom(child); } /* * Check to see if the XMITS/PCI-X workaround applies. */ n = ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_NOTPROM, "pcix-update-cmd-reg", -1); if (n != -1) { extern void pcix_set_cmd_reg(dev_info_t *child, uint16_t value); DEBUG1(DBG_INIT_CLD, child, "Turning on XMITS NCPQ " "Workaround: value = %x\n", n); pcix_set_cmd_reg(child, n); } pci_config_teardown(&config_handle); return (DDI_SUCCESS); }
int UM_PCI_Services(Adapter_Struc *pAd, union REGS *pregs) { int func = (int)pregs->h.al; unsigned long regnum; /* register number */ unsigned short vendid; unsigned short devid; unsigned long compval; switch (func) { case PCI_BIOS_PRESENT: /* return PCI present with rev 2.1 */ pregs->h.ah = 0; pregs->h.al = 0; pregs->h.bh = 2; pregs->h.bl = 1; pregs->h.cl = 1; pregs->e.edx = 0x20494350; pregs->x.cflag = 0; break; case FIND_PCI_DEVICE: vendid = pregs->x.dx; devid = pregs->x.cx; compval = (((ulong_t)devid) << 16) | ((ulong_t)vendid); if (vendid == 0xffff) { /* bad vendor id */ pregs->x.cflag = 1; pregs->h.ah = PCI_BAD_VENDOR_ID; } else { if (pci_config_get32( (ddi_acc_handle_t)pAd->pcihandle, 0) == compval) { pregs->h.bh = 0; /* put 0 to fake it */ pregs->h.bl = 0; /* put 0 to fake it */ pregs->h.ah = PCI_SUCCESSFUL; pregs->x.cflag = 0; } else { pregs->h.ah = PCI_DEVICE_NOT_FOUND; pregs->x.cflag = 1; } } break; case PCI_READ_CONFIG_BYTE: regnum = (unsigned long) pregs->h.di; pregs->h.cl = pci_config_get8( (ddi_acc_handle_t)pAd->pcihandle, regnum); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; break; case PCI_READ_CONFIG_WORD: regnum = (unsigned long)pregs->h.di; if (regnum & 0x1) { pregs->x.cflag = 1; pregs->h.ah = PCI_BAD_REGISTER_NUMBER; } else { pregs->x.cx = pci_config_get16( (ddi_acc_handle_t)pAd->pcihandle, regnum); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; } break; case PCI_READ_CONFIG_DWORD: regnum = (unsigned long)pregs->h.di; if (regnum & 0x3) { pregs->x.cflag = 1; pregs->h.ah = PCI_BAD_REGISTER_NUMBER; } else { pregs->e.ecx = pci_config_get32( (ddi_acc_handle_t)pAd->pcihandle, regnum); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; } break; case PCI_WRITE_CONFIG_BYTE: regnum = (unsigned long) pregs->h.di; pci_config_put8((ddi_acc_handle_t)pAd->pcihandle, regnum, pregs->h.cl); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; break; case PCI_WRITE_CONFIG_WORD: regnum = (unsigned long)pregs->h.di; if (regnum & 0x1) { pregs->x.cflag = 1; pregs->h.ah = PCI_BAD_REGISTER_NUMBER; } else { pci_config_put16( (ddi_acc_handle_t)pAd->pcihandle, regnum, pregs->x.cx); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; } break; case PCI_WRITE_CONFIG_DWORD: regnum = (unsigned long)pregs->h.di; if (regnum & 0x1) { pregs->x.cflag = 1; pregs->h.ah = PCI_BAD_REGISTER_NUMBER; } else { pci_config_put32( (ddi_acc_handle_t)pAd->pcihandle, regnum, pregs->e.ecx); pregs->x.cflag = 0; pregs->h.ah = PCI_SUCCESSFUL; } break; default: pregs->x.cflag = 1; /* set error */ pregs->h.ah = PCI_FUNC_NOT_SUPPORTED; break; } return (0); }
void t4_os_pci_write_cfg2(struct adapter *sc, int reg, uint16_t val) { pci_config_put16(sc->pci_regh, reg, val); }
int pcn_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { pcn_t *pcnp; mac_register_t *macp; const pcn_type_t *pcn_type; int instance = ddi_get_instance(dip); int rc; ddi_acc_handle_t pci; uint16_t venid; uint16_t devid; uint16_t svid; uint16_t ssid; switch (cmd) { case DDI_RESUME: return (pcn_ddi_resume(dip)); case DDI_ATTACH: break; default: return (DDI_FAILURE); } if (ddi_slaveonly(dip) == DDI_SUCCESS) { pcn_error(dip, "slot does not support PCI bus-master"); return (DDI_FAILURE); } if (ddi_intr_hilevel(dip, 0) != 0) { pcn_error(dip, "hilevel interrupts not supported"); return (DDI_FAILURE); } if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { pcn_error(dip, "unable to setup PCI config handle"); return (DDI_FAILURE); } venid = pci_config_get16(pci, PCI_CONF_VENID); devid = pci_config_get16(pci, PCI_CONF_DEVID); svid = pci_config_get16(pci, PCI_CONF_SUBVENID); ssid = pci_config_get16(pci, PCI_CONF_SUBSYSID); if ((pcn_type = pcn_match(venid, devid)) == NULL) { pci_config_teardown(&pci); pcn_error(dip, "Unable to identify PCI card"); return (DDI_FAILURE); } if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model", pcn_type->pcn_name) != DDI_PROP_SUCCESS) { pci_config_teardown(&pci); pcn_error(dip, "Unable to create model property"); return (DDI_FAILURE); } if (ddi_soft_state_zalloc(pcn_ssp, instance) != DDI_SUCCESS) { pcn_error(dip, "Unable to allocate soft state"); pci_config_teardown(&pci); return (DDI_FAILURE); } pcnp = ddi_get_soft_state(pcn_ssp, instance); pcnp->pcn_dip = dip; pcnp->pcn_instance = instance; pcnp->pcn_extphyaddr = -1; if (ddi_get_iblock_cookie(dip, 0, &pcnp->pcn_icookie) != DDI_SUCCESS) { pcn_error(pcnp->pcn_dip, "ddi_get_iblock_cookie failed"); ddi_soft_state_free(pcn_ssp, instance); pci_config_teardown(&pci); return (DDI_FAILURE); } mutex_init(&pcnp->pcn_xmtlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); mutex_init(&pcnp->pcn_intrlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); mutex_init(&pcnp->pcn_reglock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie); /* * Enable bus master, IO space, and memory space accesses */ pci_config_put16(pci, PCI_CONF_COMM, pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_ME | PCI_COMM_MAE); pci_config_teardown(&pci); if (ddi_regs_map_setup(dip, 1, (caddr_t *)&pcnp->pcn_regs, 0, 0, &pcn_devattr, &pcnp->pcn_regshandle)) { pcn_error(dip, "ddi_regs_map_setup failed"); goto fail; } if (pcn_set_chipid(pcnp, (uint32_t)ssid << 16 | (uint32_t)svid) != DDI_SUCCESS) { goto fail; } if ((pcnp->pcn_mii = mii_alloc(pcnp, dip, &pcn_mii_ops)) == NULL) goto fail; /* XXX: need to set based on device */ mii_set_pauseable(pcnp->pcn_mii, B_FALSE, B_FALSE); if ((pcn_allocrxring(pcnp) != DDI_SUCCESS) || (pcn_alloctxring(pcnp) != DDI_SUCCESS)) { pcn_error(dip, "unable to allocate DMA resources"); goto fail; } pcnp->pcn_promisc = B_FALSE; mutex_enter(&pcnp->pcn_intrlock); mutex_enter(&pcnp->pcn_xmtlock); rc = pcn_initialize(pcnp, B_TRUE); mutex_exit(&pcnp->pcn_xmtlock); mutex_exit(&pcnp->pcn_intrlock); if (rc != DDI_SUCCESS) goto fail; if (ddi_add_intr(dip, 0, NULL, NULL, pcn_intr, (caddr_t)pcnp) != DDI_SUCCESS) { pcn_error(dip, "unable to add interrupt"); goto fail; } pcnp->pcn_flags |= PCN_INTR_ENABLED; if ((macp = mac_alloc(MAC_VERSION)) == NULL) { pcn_error(pcnp->pcn_dip, "mac_alloc failed"); goto fail; } macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macp->m_driver = pcnp; macp->m_dip = dip; macp->m_src_addr = pcnp->pcn_addr; macp->m_callbacks = &pcn_m_callbacks; macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; if (mac_register(macp, &pcnp->pcn_mh) == DDI_SUCCESS) { mac_free(macp); return (DDI_SUCCESS); } mac_free(macp); return (DDI_SUCCESS); fail: pcn_teardown(pcnp); return (DDI_FAILURE); }
/* * audioixp_attach() * * Description: * Attach an instance of the audioixp driver. This routine does * the device dependent attach tasks. * * Arguments: * dev_info_t *dip Pointer to the device's dev_info struct * ddi_attach_cmd_t cmd Attach command * * Returns: * DDI_SUCCESS The driver was initialized properly * DDI_FAILURE The driver couldn't be initialized properly */ static int audioixp_attach(dev_info_t *dip) { uint16_t cmdeg; audioixp_state_t *statep; audio_dev_t *adev; uint32_t devid; const char *name; const char *rev; /* we don't support high level interrupts in the driver */ if (ddi_intr_hilevel(dip, 0) != 0) { cmn_err(CE_WARN, "!%s%d: unsupported high level interrupt", ddi_driver_name(dip), ddi_get_instance(dip)); return (DDI_FAILURE); } /* allocate the soft state structure */ statep = kmem_zalloc(sizeof (*statep), KM_SLEEP); statep->dip = dip; ddi_set_driver_private(dip, statep); if (ddi_get_iblock_cookie(dip, 0, &statep->iblock) != DDI_SUCCESS) { cmn_err(CE_WARN, "!%s%d: cannot get iblock cookie", ddi_driver_name(dip), ddi_get_instance(dip)); kmem_free(statep, sizeof (*statep)); return (DDI_FAILURE); } mutex_init(&statep->inst_lock, NULL, MUTEX_DRIVER, statep->iblock); /* allocate framework audio device */ if ((adev = audio_dev_alloc(dip, 0)) == NULL) { cmn_err(CE_WARN, "!%s%d: unable to allocate audio dev", ddi_driver_name(dip), ddi_get_instance(dip)); goto error; } statep->adev = adev; /* map in the registers */ if (audioixp_map_regs(statep) != DDI_SUCCESS) { audio_dev_warn(adev, "couldn't map registers"); goto error; } /* set device information -- this could be smarter */ devid = ((pci_config_get16(statep->pcih, PCI_CONF_VENID)) << 16) | pci_config_get16(statep->pcih, PCI_CONF_DEVID); name = "ATI AC'97"; switch (devid) { case IXP_PCI_ID_200: rev = "IXP150"; break; case IXP_PCI_ID_300: rev = "SB300"; break; case IXP_PCI_ID_400: if (pci_config_get8(statep->pcih, PCI_CONF_REVID) & 0x80) { rev = "SB450"; } else { rev = "SB400"; } break; case IXP_PCI_ID_SB600: rev = "SB600"; break; default: rev = "Unknown"; break; } audio_dev_set_description(adev, name); audio_dev_set_version(adev, rev); /* allocate port structures */ if ((audioixp_alloc_port(statep, IXP_PLAY) != DDI_SUCCESS) || (audioixp_alloc_port(statep, IXP_REC) != DDI_SUCCESS)) { goto error; } statep->ac97 = ac97_alloc(dip, audioixp_rd97, audioixp_wr97, statep); if (statep->ac97 == NULL) { audio_dev_warn(adev, "failed to allocate ac97 handle"); goto error; } /* set PCI command register */ cmdeg = pci_config_get16(statep->pcih, PCI_CONF_COMM); pci_config_put16(statep->pcih, PCI_CONF_COMM, cmdeg | PCI_COMM_IO | PCI_COMM_MAE); /* set up kernel statistics */ if ((statep->ksp = kstat_create(IXP_NAME, ddi_get_instance(dip), IXP_NAME, "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT)) != NULL) { kstat_install(statep->ksp); } if (audioixp_chip_init(statep) != DDI_SUCCESS) { audio_dev_warn(statep->adev, "failed to init chip"); goto error; } /* initialize the AC'97 part */ if (ac97_init(statep->ac97, adev) != DDI_SUCCESS) { audio_dev_warn(adev, "ac'97 initialization failed"); goto error; } /* set up the interrupt handler */ if (ddi_add_intr(dip, 0, &statep->iblock, NULL, audioixp_intr, (caddr_t)statep) != DDI_SUCCESS) { audio_dev_warn(adev, "bad interrupt specification"); } statep->intr_added = B_TRUE; if (audio_dev_register(adev) != DDI_SUCCESS) { audio_dev_warn(adev, "unable to register with framework"); goto error; } ddi_report_dev(dip); return (DDI_SUCCESS); error: audioixp_destroy(statep); return (DDI_FAILURE); }
static int pci_initchild(dev_info_t *child) { char name[80]; ddi_acc_handle_t config_handle; ushort_t command_preserve, command; if (pci_common_name_child(child, name, 80) != DDI_SUCCESS) { return (DDI_FAILURE); } ddi_set_name_addr(child, name); /* * Pseudo nodes indicate a prototype node with per-instance * properties to be merged into the real h/w device node. * The interpretation of the unit-address is DD[,F] * where DD is the device id and F is the function. */ if (ndi_dev_is_persistent_node(child) == 0) { extern int pci_allow_pseudo_children; ddi_set_parent_data(child, NULL); /* * Try to merge the properties from this prototype * node into real h/w nodes. */ if (ndi_merge_node(child, pci_common_name_child) == DDI_SUCCESS) { /* * Merged ok - return failure to remove the node. */ ddi_set_name_addr(child, NULL); return (DDI_FAILURE); } /* workaround for ddivs to run under PCI */ if (pci_allow_pseudo_children) { /* * If the "interrupts" property doesn't exist, * this must be the ddivs no-intr case, and it returns * DDI_SUCCESS instead of DDI_FAILURE. */ if (ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "interrupts", -1) == -1) return (DDI_SUCCESS); /* * Create the ddi_parent_private_data for a pseudo * child. */ pci_common_set_parent_private_data(child); return (DDI_SUCCESS); } /* * The child was not merged into a h/w node, * but there's not much we can do with it other * than return failure to cause the node to be removed. */ cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", ddi_get_name(child), ddi_get_name_addr(child), ddi_get_name(child)); ddi_set_name_addr(child, NULL); return (DDI_NOT_WELL_FORMED); } if (ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "interrupts", -1) != -1) pci_common_set_parent_private_data(child); else ddi_set_parent_data(child, NULL); /* * initialize command register */ if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) return (DDI_FAILURE); /* * Support for the "command-preserve" property. */ command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "command-preserve", 0); command = pci_config_get16(config_handle, PCI_CONF_COMM); command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); command |= (pci_command_default & ~command_preserve); pci_config_put16(config_handle, PCI_CONF_COMM, command); pci_config_teardown(&config_handle); return (DDI_SUCCESS); }
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) { pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); }
static int acebus_config(ebus_devstate_t *ebus_p) { ddi_acc_handle_t conf_handle; uint16_t comm; #ifdef ACEBUS_HOTPLUG int tcr_reg; caddr_t csr_io; ddi_device_acc_attr_t csr_attr = { /* CSR map attributes */ DDI_DEVICE_ATTR_V0, DDI_STRUCTURE_LE_ACC, DDI_STRICTORDER_ACC }; ddi_acc_handle_t csr_handle; #endif /* * Make sure the master enable and memory access enable * bits are set in the config command register. */ if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS) return (0); comm = pci_config_get16(conf_handle, PCI_CONF_COMM), #ifdef DEBUG DBG1(D_ATTACH, ebus_p, "command register was 0x%x\n", comm); #endif comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE| PCI_COMM_PARITY_DETECT); pci_config_put16(conf_handle, PCI_CONF_COMM, comm), #ifdef DEBUG DBG1(D_MAP, ebus_p, "command register is now 0x%x\n", pci_config_get16(conf_handle, PCI_CONF_COMM)); #endif pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ, (uchar_t)acebus_cache_line_size); pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER, (uchar_t)acebus_latency_timer); pci_config_teardown(&conf_handle); #ifdef ACEBUS_HOTPLUG if (acebus_update_props(ebus_p) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Could not update special properties.", ddi_driver_name(ebus_p->dip), ddi_get_instance(ebus_p->dip)); return (0); } if (ddi_regs_map_setup(ebus_p->dip, CSR_IO_RINDEX, (caddr_t *)&csr_io, 0, CSR_SIZE, &csr_attr, &csr_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: Could not map Ebus CSR.", ddi_driver_name(ebus_p->dip), ddi_get_instance(ebus_p->dip)); } #ifdef DEBUG if (acebus_debug_flags) { DBG3(D_ATTACH, ebus_p, "tcr[123] = %x,%x,%x\n", ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF)), ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF)), ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF))); DBG2(D_ATTACH, ebus_p, "pmd-aux=%x, freq-aux=%x\n", ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + PMD_AUX_OFF)), ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + FREQ_AUX_OFF))); #ifdef ACEBUS_DEBUG for (comm = 0; comm < 4; comm++) prom_printf("dcsr%d=%x, dacr%d=%x, dbcr%d=%x\n", comm, ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 0x700000+(0x2000*comm))), comm, ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 0x700000+(0x2000*comm)+4)), comm, ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 0x700000+(0x2000*comm)+8))); #endif } /* acebus_debug_flags */ #endif /* If TCR registers are not initialized, initialize them here */ tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF)); if ((tcr_reg == 0) || (tcr_reg == -1)) ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF), TCR1_REGVAL); tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF)); if ((tcr_reg == 0) || (tcr_reg == -1)) ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF), TCR2_REGVAL); tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF)); if ((tcr_reg == 0) || (tcr_reg == -1)) ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF), TCR3_REGVAL); #ifdef DEBUG if (acebus_debug_flags) { DBG3(D_ATTACH, ebus_p, "wrote tcr[123] = %x,%x,%x\n", ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF)), ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF)), ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF))); } #endif ddi_regs_map_free(&csr_handle); #endif /* ACEBUS_HOTPLUG */ return (1); /* return success */ }
static int ppb_initchild(dev_info_t *child) { struct ddi_parent_private_data *pdptr; ppb_devstate_t *ppb; char name[MAXNAMELEN]; ddi_acc_handle_t config_handle; ushort_t command_preserve, command; ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state, ddi_get_instance(ddi_get_parent(child))); if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) return (DDI_FAILURE); ddi_set_name_addr(child, name); /* * Pseudo nodes indicate a prototype node with per-instance * properties to be merged into the real h/w device node. * The interpretation of the unit-address is DD[,F] * where DD is the device id and F is the function. */ if (ndi_dev_is_persistent_node(child) == 0) { extern int pci_allow_pseudo_children; ddi_set_parent_data(child, NULL); /* * Try to merge the properties from this prototype * node into real h/w nodes. */ if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) { /* * Merged ok - return failure to remove the node. */ ddi_set_name_addr(child, NULL); return (DDI_FAILURE); } /* workaround for ddivs to run under PCI */ if (pci_allow_pseudo_children) return (DDI_SUCCESS); /* * The child was not merged into a h/w node, * but there's not much we can do with it other * than return failure to cause the node to be removed. */ cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", ddi_driver_name(child), ddi_get_name_addr(child), ddi_driver_name(child)); ddi_set_name_addr(child, NULL); return (DDI_NOT_WELL_FORMED); } ddi_set_parent_data(child, NULL); /* * PCIe FMA specific * * Note: parent_data for parent is created only if this is PCI-E * platform, for which, SG take a different route to handle device * errors. */ if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) { if (pcie_init_cfghdl(child) != DDI_SUCCESS) return (DDI_FAILURE); pcie_init_dom(child); } /* transfer select properties from PROM to kernel */ if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, "interrupts", -1) != -1) { pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) + sizeof (struct intrspec)), KM_SLEEP); pdptr->par_intr = (struct intrspec *)(pdptr + 1); pdptr->par_nintr = 1; ddi_set_parent_data(child, pdptr); } else ddi_set_parent_data(child, NULL); if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) { pcie_fini_dom(child); return (DDI_FAILURE); } /* * Support for the "command-preserve" property. */ command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, "command-preserve", 0); command = pci_config_get16(config_handle, PCI_CONF_COMM); command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); command |= (ppb_command_default & ~command_preserve); pci_config_put16(config_handle, PCI_CONF_COMM, command); pci_config_teardown(&config_handle); return (DDI_SUCCESS); }
/* * Autoconfiguration entry points. */ int efe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { ddi_acc_handle_t pci; int types; int count; int actual; uint_t pri; efe_t *efep; mac_register_t *macp; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: efep = ddi_get_driver_private(dip); return (efe_resume(efep)); default: return (DDI_FAILURE); } /* * PCI configuration. */ if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { efe_error(dip, "unable to setup PCI configuration!"); return (DDI_FAILURE); } pci_config_put16(pci, PCI_CONF_COMM, pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_MAE | PCI_COMM_ME); pci_config_teardown(&pci); if (ddi_intr_get_supported_types(dip, &types) != DDI_SUCCESS || !(types & DDI_INTR_TYPE_FIXED)) { efe_error(dip, "fixed interrupts not supported!"); return (DDI_FAILURE); } if (ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &count) != DDI_SUCCESS || count != 1) { efe_error(dip, "no fixed interrupts available!"); return (DDI_FAILURE); } /* * Initialize soft state. */ efep = kmem_zalloc(sizeof (efe_t), KM_SLEEP); ddi_set_driver_private(dip, efep); efep->efe_dip = dip; if (ddi_regs_map_setup(dip, 1, (caddr_t *)&efep->efe_regs, 0, 0, &efe_regs_acc_attr, &efep->efe_regs_acch) != DDI_SUCCESS) { efe_error(dip, "unable to setup register mapping!"); goto failure; } efep->efe_rx_ring = efe_ring_alloc(efep->efe_dip, RXDESCL); if (efep->efe_rx_ring == NULL) { efe_error(efep->efe_dip, "unable to allocate rx ring!"); goto failure; } efep->efe_tx_ring = efe_ring_alloc(efep->efe_dip, TXDESCL); if (efep->efe_tx_ring == NULL) { efe_error(efep->efe_dip, "unable to allocate tx ring!"); goto failure; } if (ddi_intr_alloc(dip, &efep->efe_intrh, DDI_INTR_TYPE_FIXED, 0, count, &actual, DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS || actual != count) { efe_error(dip, "unable to allocate fixed interrupt!"); goto failure; } if (ddi_intr_get_pri(efep->efe_intrh, &pri) != DDI_SUCCESS || pri >= ddi_intr_get_hilevel_pri()) { efe_error(dip, "unable to get valid interrupt priority!"); goto failure; } mutex_init(&efep->efe_intrlock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); mutex_init(&efep->efe_txlock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); /* * Initialize device. */ mutex_enter(&efep->efe_intrlock); mutex_enter(&efep->efe_txlock); efe_reset(efep); mutex_exit(&efep->efe_txlock); mutex_exit(&efep->efe_intrlock); /* Use factory address as default */ efe_getaddr(efep, efep->efe_macaddr); /* * Enable the ISR. */ if (ddi_intr_add_handler(efep->efe_intrh, efe_intr, efep, NULL) != DDI_SUCCESS) { efe_error(dip, "unable to add interrupt handler!"); goto failure; } if (ddi_intr_enable(efep->efe_intrh) != DDI_SUCCESS) { efe_error(dip, "unable to enable interrupt!"); goto failure; } /* * Allocate MII resources. */ if ((efep->efe_miih = mii_alloc(efep, dip, &efe_mii_ops)) == NULL) { efe_error(dip, "unable to allocate mii resources!"); goto failure; } /* * Allocate MAC resources. */ if ((macp = mac_alloc(MAC_VERSION)) == NULL) { efe_error(dip, "unable to allocate mac resources!"); goto failure; } macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; macp->m_driver = efep; macp->m_dip = dip; macp->m_src_addr = efep->efe_macaddr; macp->m_callbacks = &efe_m_callbacks; macp->m_min_sdu = 0; macp->m_max_sdu = ETHERMTU; macp->m_margin = VLAN_TAGSZ; if (mac_register(macp, &efep->efe_mh) != 0) { efe_error(dip, "unable to register with mac!"); goto failure; } mac_free(macp); ddi_report_dev(dip); return (DDI_SUCCESS); failure: if (macp != NULL) { mac_free(macp); } if (efep->efe_miih != NULL) { mii_free(efep->efe_miih); } if (efep->efe_intrh != NULL) { (void) ddi_intr_disable(efep->efe_intrh); (void) ddi_intr_remove_handler(efep->efe_intrh); (void) ddi_intr_free(efep->efe_intrh); } mutex_destroy(&efep->efe_txlock); mutex_destroy(&efep->efe_intrlock); if (efep->efe_tx_ring != NULL) { efe_ring_free(&efep->efe_tx_ring); } if (efep->efe_rx_ring != NULL) { efe_ring_free(&efep->efe_rx_ring); } if (efep->efe_regs_acch != NULL) { ddi_regs_map_free(&efep->efe_regs_acch); } kmem_free(efep, sizeof (efe_t)); return (DDI_FAILURE); }
void pciconfig_bar(void *instance, uint32_t offset, char *name) { struct e1000g *Adapter = (struct e1000g *)instance; ddi_acc_handle_t handle = Adapter->osdep.cfg_handle; uint32_t base = pci_config_get32(handle, offset); uint16_t comm = pci_config_get16(handle, PCI_CONF_COMM); uint32_t size; /* derived size of the region */ uint32_t bits_comm; /* command word bits to disable */ uint32_t size_mask; /* mask for size extraction */ char tag_type[32]; /* tag to show memory vs. i/o */ char tag_mem[32]; /* tag to show memory characteristiccs */ /* base address zero, simple print */ if (base == 0) { e1000g_log(Adapter, CE_CONT, "%s:\t0x%x\n", name, base); /* base address non-zero, get size */ } else { /* i/o factors that decode from the base address */ if (base & PCI_BASE_SPACE_IO) { bits_comm = PCI_COMM_IO; size_mask = PCI_BASE_IO_ADDR_M; (void) strcpy(tag_type, "i/o port size:"); (void) strcpy(tag_mem, ""); /* memory factors that decode from the base address */ } else { bits_comm = PCI_COMM_MAE; size_mask = PCI_BASE_M_ADDR_M; (void) strcpy(tag_type, "memory size:"); if (base & PCI_BASE_TYPE_ALL) (void) strcpy(tag_mem, "64bit "); else (void) strcpy(tag_mem, "32bit "); if (base & PCI_BASE_PREF_M) (void) strcat(tag_mem, "prefetchable"); else (void) strcat(tag_mem, "non-prefetchable"); } /* disable memory decode */ pci_config_put16(handle, PCI_CONF_COMM, (comm & ~bits_comm)); /* write to base register */ pci_config_put32(handle, offset, 0xffffffff); /* read back & compute size */ size = pci_config_get32(handle, offset); size &= size_mask; size = (~size) + 1; /* restore base register */ pci_config_put32(handle, offset, base); /* re-enable memory decode */ pci_config_put16(handle, PCI_CONF_COMM, comm); /* print results */ e1000g_log(Adapter, CE_CONT, "%s:\t0x%x %s 0x%x %s\n", name, base, tag_type, size, tag_mem); } }