/* * Initialize memory controller's data structure and status. */ static int fipe_mc_init(dev_info_t *dip) { ddi_acc_handle_t handle; bzero(&fipe_mc_ctrl, sizeof (fipe_mc_ctrl)); /* Hold one reference count and will be released in fipe_mc_fini. */ ndi_hold_devi(dip); /* Setup pci configuration handler. */ if (pci_config_setup(dip, &handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "!fipe: failed to setup pcicfg handler in mc_init."); ndi_rele_devi(dip); return (-1); } /* Save original configuration. */ fipe_mc_ctrl.mc_thrtctrl = pci_config_get8(handle, FIPE_MC_THRTCTRL); fipe_mc_ctrl.mc_thrtlow = pci_config_get8(handle, FIPE_MC_THRTLOW); fipe_mc_ctrl.mc_gblact = pci_config_get8(handle, FIPE_MC_GBLACT); fipe_mc_ctrl.mc_dip = dip; fipe_mc_ctrl.mc_pci_hdl = handle; fipe_mc_ctrl.mc_initialized = B_TRUE; return (0); }
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)); }
/* * pcmu_init_child * * This function is called from our control ops routine on a * DDI_CTLOPS_INITCHILD request. It builds and sets the device's * parent private data area. * * used by: pcmu_ctlops() * * return value: none */ int pcmu_init_child(pcmu_t *pcmu_p, dev_info_t *child) { char name[10]; ddi_acc_handle_t config_handle; uint8_t bcr; uint8_t header_type; if (name_child(child, name, 10) != DDI_SUCCESS) return (DDI_FAILURE); ddi_set_name_addr(child, name); PCMU_DBG2(PCMU_DBG_PWR, ddi_get_parent(child), "INITCHILD: config regs setup for %s@%s\n", ddi_node_name(child), ddi_get_name_addr(child)); /* * Map the child configuration space to for initialization. * We assume the obp will do the following in the devices * config space: * * Set the latency-timer register to values appropriate * for the devices on the bus (based on other devices * MIN_GNT and MAX_LAT registers. * * Set the fast back-to-back enable bit in the command * register if it's supported and all devices on the bus * have the capability. * */ if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) { ddi_set_name_addr(child, NULL); return (DDI_FAILURE); } /* * Determine the configuration header type. */ header_type = pci_config_get8(config_handle, PCI_CONF_HEADER); PCMU_DBG2(PCMU_DBG_INIT_CLD, pcmu_p->pcmu_dip, "%s: header_type=%x\n", ddi_driver_name(child), header_type); /* * 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 (pcmu_command_default & PCI_COMM_PARITY_DETECT) bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE; if (pcmu_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); } pci_config_teardown(&config_handle); return (DDI_SUCCESS); }
/* * Examine devinfo node to determine if it is a PCI-PCI bridge * * Returns: * 0 if not a bridge or error * 1 if a bridge */ static int psm_is_pci_bridge(dev_info_t *dip) { ddi_acc_handle_t cfg_handle; int rv = 0; if (pci_config_setup(dip, &cfg_handle) == DDI_SUCCESS) { rv = ((pci_config_get8(cfg_handle, PCI_CONF_BASCLASS) == PCI_CLASS_BRIDGE) && (pci_config_get8(cfg_handle, PCI_CONF_SUBCLASS) == PCI_BRIDGE_PCI)); pci_config_teardown(&cfg_handle); } return (rv); }
/* * agp_target_cap_find() * * Description: * This function searches the linked capability list to find the offset * of the AGP capability register. When it was not found, return 0. * This works for standard AGP chipsets, but not for some Intel chipsets, * like the I830M/I830MP/I852PM/I852GME/I855GME. It will return 0 for * these chipsets even if AGP is supported. So the offset of acapid * should be set manually in thoses cases. * * Arguments: * pci_handle ddi acc handle of pci config * * Returns: * 0 No capability pointer register found * nexcap The AGP capability pointer register offset */ static off_t agp_target_cap_find(ddi_acc_handle_t pci_handle) { off_t nextcap = 0; uint32_t ncapid = 0; uint8_t value = 0; /* Check if this device supports the capability pointer */ value = (uint8_t)(pci_config_get16(pci_handle, PCI_CONF_STAT) & PCI_CONF_CAP_MASK); if (!value) return (0); /* Get the offset of the first capability pointer from CAPPTR */ nextcap = (off_t)(pci_config_get8(pci_handle, AGP_CONF_CAPPTR)); /* Check the AGP capability from the first capability pointer */ while (nextcap) { ncapid = pci_config_get32(pci_handle, nextcap); /* * AGP3.0 rev1.0 127 the capid was assigned by the PCI SIG, * 845 data sheet page 69 */ if ((ncapid & PCI_CONF_CAPID_MASK) == AGP_CAP_ID) /* The AGP cap was found */ break; nextcap = (off_t)((ncapid & PCI_CONF_NCAPID_MASK) >> 8); } return (nextcap); }
static void rge_chip_peek_cfg(rge_t *rgep, rge_peekpoke_t *ppd) { uint64_t regval; uint64_t regno; RGE_TRACE(("rge_chip_peek_cfg($%p, $%p)", (void *)rgep, (void *)ppd)); regno = ppd->pp_acc_offset; switch (ppd->pp_acc_size) { case 1: regval = pci_config_get8(rgep->cfg_handle, regno); break; case 2: regval = pci_config_get16(rgep->cfg_handle, regno); break; case 4: regval = pci_config_get32(rgep->cfg_handle, regno); break; case 8: regval = pci_config_get64(rgep->cfg_handle, regno); break; } ppd->pp_acc_data = regval; }
/*ARGSUSED*/ uint8_t pmubus_get8(ddi_acc_impl_t *hdlp, uint8_t *addr) { ddi_acc_hdl_t *hp = (ddi_acc_hdl_t *)hdlp; pmubus_mapreq_t *pmubus_mapreqp = hp->ah_bus_private; pmubus_devstate_t *softsp = pmubus_mapreqp->mapreq_softsp; off_t offset; uint8_t value; uint8_t mask; offset = pmubus_mapreqp->mapreq_addr + (uintptr_t)addr; offset &= PMUBUS_REGOFFSET; if ((pmubus_mapreqp->mapreq_flags) & MAPREQ_SHARED_BITS) { if (addr != 0 || pmubus_mapreqp->mapreq_size != sizeof (value)) { cmn_err(CE_WARN, "pmubus_get8: load discarded, " "incorrect access addr/size"); return ((uint8_t)-1); } mask = pmubus_mapreqp->mapreq_mask; } else { mask = (uint8_t)-1; } /* gets are simple, we just issue them no locking necessary */ value = pci_config_get8(softsp->pmubus_reghdl, offset) & mask; DPRINTF(PMUBUS_RW_DEBUG, ("pmubus_get8: addr=%p offset=%lx value=%x " "mask=%x\n", (void *)addr, offset, value, mask)); return (value); }
/*ARGSUSED*/ void pmubus_put8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value) { ddi_acc_hdl_t *hp = (ddi_acc_hdl_t *)hdlp; pmubus_mapreq_t *pmubus_mapreqp = hp->ah_bus_private; pmubus_devstate_t *softsp = pmubus_mapreqp->mapreq_softsp; off_t offset; uint8_t tmp; offset = pmubus_mapreqp->mapreq_addr + (uintptr_t)addr; offset &= PMUBUS_REGOFFSET; if ((pmubus_mapreqp->mapreq_flags) & MAPREQ_SHARED_BITS) { /* * Process "bit lane" register */ DPRINTF(PMUBUS_RW_DEBUG, ("pmubus_put8: addr=%p offset=%lx " "value=%x mask=%lx\n", (void *)addr, offset, value, pmubus_mapreqp->mapreq_mask)); if (addr != 0 || pmubus_mapreqp->mapreq_size != sizeof (value)) { cmn_err(CE_WARN, "pmubus_put8: store discarded, " "incorrect access addr/size"); return; } mutex_enter(&softsp->pmubus_reg_access_lock); tmp = pci_config_get8(softsp->pmubus_reghdl, offset); tmp &= ~pmubus_mapreqp->mapreq_mask; value &= pmubus_mapreqp->mapreq_mask; tmp |= value; pci_config_put8(softsp->pmubus_reghdl, offset, tmp); mutex_exit(&softsp->pmubus_reg_access_lock); } else { /* * Process shared register */ DPRINTF(PMUBUS_RW_DEBUG, ("pmubus_put8: addr=%p offset=%lx " "value=%x\n", (void *)addr, offset, value)); pci_config_put8(softsp->pmubus_reghdl, offset, value); } /* Flush store buffers XXX Should let drivers do this. */ tmp = pci_config_get8(softsp->pmubus_reghdl, offset); }
/* * save config regs for HyperTransport devices without drivers of classes: * memory controller and hostbridge */ int npe_save_htconfig_children(dev_info_t *dip) { dev_info_t *cdip = ddi_get_child(dip); ddi_acc_handle_t cfg_hdl; uint16_t ptr; int rval = DDI_SUCCESS; uint8_t cl, scl; for (; cdip != NULL; cdip = ddi_get_next_sibling(cdip)) { if (ddi_driver_major(cdip) != DDI_MAJOR_T_NONE) continue; if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS) return (DDI_FAILURE); cl = pci_config_get8(cfg_hdl, PCI_CONF_BASCLASS); scl = pci_config_get8(cfg_hdl, PCI_CONF_SUBCLASS); if (((cl == PCI_CLASS_MEM && scl == PCI_MEM_RAM) || (cl == PCI_CLASS_BRIDGE && scl == PCI_BRIDGE_HOST)) && pci_htcap_locate(cfg_hdl, 0, 0, &ptr) == DDI_SUCCESS) { if (pci_save_config_regs(cdip) != DDI_SUCCESS) { cmn_err(CE_WARN, "Failed to save HT config " "regs for %s\n", ddi_node_name(cdip)); rval = DDI_FAILURE; } else if (ddi_prop_update_int(DDI_DEV_T_NONE, cdip, "htconfig-saved", 1) != DDI_SUCCESS) { cmn_err(CE_WARN, "Failed to set htconfig-saved " "property for %s\n", ddi_node_name(cdip)); rval = DDI_FAILURE; } } pci_config_teardown(&cfg_hdl); } return (rval); }
/*ARGSUSED*/ int plat_ide_chipreset(dev_info_t *dip, int chno) { uint8_t val; int ret = DDI_SUCCESS; if (isa_handle == NULL) { return (DDI_FAILURE); } val = pci_config_get8(isa_handle, 0x58); /* * The dip passed as the argument is not used here. * This will be needed for platforms which have multiple on-board SB, * The dip passed will be used to match the corresponding ISA node. */ switch (chno) { case 0: /* * First disable the primary channel then re-enable it. * As per ALI no wait should be required in between have * given 1ms delay in between to be on safer side. * bit 2 of register 0x58 when 0 disable the channel 0. * bit 2 of register 0x58 when 1 enables the channel 0. */ pci_config_put8(isa_handle, 0x58, val & 0xFB); drv_usecwait(1000); pci_config_put8(isa_handle, 0x58, val); break; case 1: /* * bit 3 of register 0x58 when 0 disable the channel 1. * bit 3 of register 0x58 when 1 enables the channel 1. */ pci_config_put8(isa_handle, 0x58, val & 0xF7); drv_usecwait(1000); pci_config_put8(isa_handle, 0x58, val); break; default: /* * Unknown channel number passed. Return failure. */ ret = DDI_FAILURE; } return (ret); }
/* * 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); } }
void pci_dump(void *arg) { igb_t *igb = (igb_t *)arg; ddi_acc_handle_t handle; uint8_t cap_ptr; uint8_t next_ptr; uint32_t msix_bar; uint32_t msix_ctrl; uint32_t msix_tbl_sz; uint32_t tbl_offset; uint32_t tbl_bir; uint32_t pba_offset; uint32_t pba_bir; off_t offset; off_t mem_size; uintptr_t base; ddi_acc_handle_t acc_hdl; int i; handle = igb->osdep.cfg_handle; igb_log(igb, "Begin dump PCI config space"); igb_log(igb, "PCI_CONF_VENID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_VENID)); igb_log(igb, "PCI_CONF_DEVID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_DEVID)); igb_log(igb, "PCI_CONF_COMMAND:\t0x%x\n", pci_config_get16(handle, PCI_CONF_COMM)); igb_log(igb, "PCI_CONF_STATUS:\t0x%x\n", pci_config_get16(handle, PCI_CONF_STAT)); igb_log(igb, "PCI_CONF_REVID:\t0x%x\n", pci_config_get8(handle, PCI_CONF_REVID)); igb_log(igb, "PCI_CONF_PROG_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_PROGCLASS)); igb_log(igb, "PCI_CONF_SUB_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_SUBCLASS)); igb_log(igb, "PCI_CONF_BAS_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_BASCLASS)); igb_log(igb, "PCI_CONF_CACHE_LINESZ:\t0x%x\n", pci_config_get8(handle, PCI_CONF_CACHE_LINESZ)); igb_log(igb, "PCI_CONF_LATENCY_TIMER:\t0x%x\n", pci_config_get8(handle, PCI_CONF_LATENCY_TIMER)); igb_log(igb, "PCI_CONF_HEADER_TYPE:\t0x%x\n", pci_config_get8(handle, PCI_CONF_HEADER)); igb_log(igb, "PCI_CONF_BIST:\t0x%x\n", pci_config_get8(handle, PCI_CONF_BIST)); igb_log(igb, "PCI_CONF_BASE0:\t0x%x\n", pci_config_get32(handle, PCI_CONF_BASE0)); igb_log(igb, "PCI_CONF_BASE1:\t0x%x\n", pci_config_get32(handle, PCI_CONF_BASE1)); igb_log(igb, "PCI_CONF_BASE2:\t0x%x\n", pci_config_get32(handle, PCI_CONF_BASE2)); /* MSI-X BAR */ msix_bar = pci_config_get32(handle, PCI_CONF_BASE3); igb_log(igb, "PCI_CONF_BASE3:\t0x%x\n", msix_bar); igb_log(igb, "PCI_CONF_BASE4:\t0x%x\n", pci_config_get32(handle, PCI_CONF_BASE4)); igb_log(igb, "PCI_CONF_BASE5:\t0x%x\n", pci_config_get32(handle, PCI_CONF_BASE5)); igb_log(igb, "PCI_CONF_CIS:\t0x%x\n", pci_config_get32(handle, PCI_CONF_CIS)); igb_log(igb, "PCI_CONF_SUBVENID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_SUBVENID)); igb_log(igb, "PCI_CONF_SUBSYSID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_SUBSYSID)); igb_log(igb, "PCI_CONF_ROM:\t0x%x\n", pci_config_get32(handle, PCI_CONF_ROM)); cap_ptr = pci_config_get8(handle, PCI_CONF_CAP_PTR); igb_log(igb, "PCI_CONF_CAP_PTR:\t0x%x\n", cap_ptr); igb_log(igb, "PCI_CONF_ILINE:\t0x%x\n", pci_config_get8(handle, PCI_CONF_ILINE)); igb_log(igb, "PCI_CONF_IPIN:\t0x%x\n", pci_config_get8(handle, PCI_CONF_IPIN)); igb_log(igb, "PCI_CONF_MIN_G:\t0x%x\n", pci_config_get8(handle, PCI_CONF_MIN_G)); igb_log(igb, "PCI_CONF_MAX_L:\t0x%x\n", pci_config_get8(handle, PCI_CONF_MAX_L)); /* Power Management */ offset = cap_ptr; igb_log(igb, "PCI_PM_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset)); next_ptr = pci_config_get8(handle, offset + 1); igb_log(igb, "PCI_PM_NEXT_PTR:\t0x%x\n", next_ptr); igb_log(igb, "PCI_PM_CAP:\t0x%x\n", pci_config_get16(handle, offset + PCI_PMCAP)); igb_log(igb, "PCI_PM_CSR:\t0x%x\n", pci_config_get16(handle, offset + PCI_PMCSR)); igb_log(igb, "PCI_PM_CSR_BSE:\t0x%x\n", pci_config_get8(handle, offset + PCI_PMCSR_BSE)); igb_log(igb, "PCI_PM_DATA:\t0x%x\n", pci_config_get8(handle, offset + PCI_PMDATA)); /* MSI Configuration */ offset = next_ptr; igb_log(igb, "PCI_MSI_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset)); next_ptr = pci_config_get8(handle, offset + 1); igb_log(igb, "PCI_MSI_NEXT_PTR:\t0x%x\n", next_ptr); igb_log(igb, "PCI_MSI_CTRL:\t0x%x\n", pci_config_get16(handle, offset + PCI_MSI_CTRL)); igb_log(igb, "PCI_MSI_ADDR:\t0x%x\n", pci_config_get32(handle, offset + PCI_MSI_ADDR_OFFSET)); igb_log(igb, "PCI_MSI_ADDR_HI:\t0x%x\n", pci_config_get32(handle, offset + 0x8)); igb_log(igb, "PCI_MSI_DATA:\t0x%x\n", pci_config_get16(handle, offset + 0xC)); /* MSI-X Configuration */ offset = next_ptr; igb_log(igb, "PCI_MSIX_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset)); next_ptr = pci_config_get8(handle, offset + 1); igb_log(igb, "PCI_MSIX_NEXT_PTR:\t0x%x\n", next_ptr); msix_ctrl = pci_config_get16(handle, offset + PCI_MSIX_CTRL); msix_tbl_sz = msix_ctrl & 0x7ff; igb_log(igb, "PCI_MSIX_CTRL:\t0x%x\n", msix_ctrl); tbl_offset = pci_config_get32(handle, offset + PCI_MSIX_TBL_OFFSET); tbl_bir = tbl_offset & PCI_MSIX_TBL_BIR_MASK; tbl_offset = tbl_offset & ~PCI_MSIX_TBL_BIR_MASK; igb_log(igb, "PCI_MSIX_TBL_OFFSET:\t0x%x\n", tbl_offset); igb_log(igb, "PCI_MSIX_TBL_BIR:\t0x%x\n", tbl_bir); pba_offset = pci_config_get32(handle, offset + PCI_MSIX_PBA_OFFSET); pba_bir = pba_offset & PCI_MSIX_PBA_BIR_MASK; pba_offset = pba_offset & ~PCI_MSIX_PBA_BIR_MASK; igb_log(igb, "PCI_MSIX_PBA_OFFSET:\t0x%x\n", pba_offset); igb_log(igb, "PCI_MSIX_PBA_BIR:\t0x%x\n", pba_bir); /* PCI Express Configuration */ offset = next_ptr; igb_log(igb, "PCIE_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset + PCIE_CAP_ID)); next_ptr = pci_config_get8(handle, offset + PCIE_CAP_NEXT_PTR); igb_log(igb, "PCIE_CAP_NEXT_PTR:\t0x%x\n", next_ptr); igb_log(igb, "PCIE_PCIECAP:\t0x%x\n", pci_config_get16(handle, offset + PCIE_PCIECAP)); igb_log(igb, "PCIE_DEVCAP:\t0x%x\n", pci_config_get32(handle, offset + PCIE_DEVCAP)); igb_log(igb, "PCIE_DEVCTL:\t0x%x\n", pci_config_get16(handle, offset + PCIE_DEVCTL)); igb_log(igb, "PCIE_DEVSTS:\t0x%x\n", pci_config_get16(handle, offset + PCIE_DEVSTS)); igb_log(igb, "PCIE_LINKCAP:\t0x%x\n", pci_config_get32(handle, offset + PCIE_LINKCAP)); igb_log(igb, "PCIE_LINKCTL:\t0x%x\n", pci_config_get16(handle, offset + PCIE_LINKCTL)); igb_log(igb, "PCIE_LINKSTS:\t0x%x\n", pci_config_get16(handle, offset + PCIE_LINKSTS)); /* MSI-X Memory Space */ if (ddi_dev_regsize(igb->dip, IGB_ADAPTER_MSIXTAB, &mem_size) != DDI_SUCCESS) { igb_log(igb, "ddi_dev_regsize() failed"); return; } if ((ddi_regs_map_setup(igb->dip, IGB_ADAPTER_MSIXTAB, (caddr_t *)&base, 0, mem_size, &igb_regs_acc_attr, &acc_hdl)) != DDI_SUCCESS) { igb_log(igb, "ddi_regs_map_setup() failed"); return; } igb_log(igb, "MSI-X Memory Space: (mem_size = %d, base = %x)", mem_size, base); for (i = 0; i <= msix_tbl_sz; i++) { igb_log(igb, "MSI-X Table Entry(%d):", i); igb_log(igb, "lo_addr:\t%x", ddi_get32(acc_hdl, (uint32_t *)(base + tbl_offset + (i * 16)))); igb_log(igb, "up_addr:\t%x", ddi_get32(acc_hdl, (uint32_t *)(base + tbl_offset + (i * 16) + 4))); igb_log(igb, "msg_data:\t%x", ddi_get32(acc_hdl, (uint32_t *)(base + tbl_offset + (i * 16) + 8))); igb_log(igb, "vct_ctrl:\t%x", ddi_get32(acc_hdl, (uint32_t *)(base + tbl_offset + (i * 16) + 12))); } igb_log(igb, "MSI-X Pending Bits:\t%x", ddi_get32(acc_hdl, (uint32_t *)(base + pba_offset))); ddi_regs_map_free(&acc_hdl); }
static size_t i8xx_biosmem_detect(agp_target_softstate_t *softstate) { uint8_t memval; size_t kbytes; switch (softstate->tsoft_devid) { case INTEL_BR_810: case INTEL_BR_810DC: case INTEL_BR_810E: memval = pci_config_get8(softstate->tsoft_pcihdl, I810_CONF_SMRAM); switch (memval & I810_GMS_MASK) { case 0x80: kbytes = 512; /* 512K preallocated memory */ break; case 0xc0: kbytes = 1024; /* 1024K preallocated memory */ break; default: kbytes = 0; /* an unexpected case */ } break; case INTEL_BR_830M: case INTEL_BR_845: memval = pci_config_get8(softstate->tsoft_pcihdl, I8XX_CONF_GC); switch (memval & I8XX_GC_MODE_MASK) { case I8XX_GC_MODE2: kbytes = 512; /* 512K preallocated memory */ break; case I8XX_GC_MODE3: kbytes = 1024; /* 1M preallocated memory */ break; case I8XX_GC_MODE4: kbytes = 8 * 1024; /* 8M preallocated memory */ break; default: kbytes = 0; /* an unexpected case */ } break; case INTEL_BR_855GM: memval = pci_config_get8(softstate->tsoft_pcihdl, I8XX_CONF_GC); switch (memval & I8XX_GC_MODE_MASK) { case I8XX_GC_MODE1: kbytes = 1024; /* 1M preallocated memory */ break; case I8XX_GC_MODE2: kbytes = 4 * 1024; /* 4M preallocated memory */ break; case I8XX_GC_MODE3: kbytes = 8 * 1024; /* 8M preallocated memory */ break; case I8XX_GC_MODE4: kbytes = 16 * 1024; /* 16M preallocated memory */ break; case I8XX_GC_MODE5: kbytes = 32 * 1024; /* 32M preallocated memory */ break; default: kbytes = 0; /* an unexpected case */ } break; case INTEL_BR_865: memval = pci_config_get8(softstate->tsoft_pcihdl, I8XX_CONF_GC); switch (memval & I8XX_GC_MODE_MASK) { case I8XX_GC_MODE1: kbytes = 1024; /* 1M preallocated memory */ break; case I8XX_GC_MODE3: kbytes = 8 * 1024; /* 8M preallocated memory */ break; case I8XX_GC_MODE4: kbytes = 16 * 1024; /* 16M preallocated memory */ break; default: kbytes = 0; /* an unexpected case */ } break; case INTEL_BR_910: case INTEL_BR_910M: memval = pci_config_get8(softstate->tsoft_pcihdl, I8XX_CONF_GC); switch (memval & I8XX_GC_MODE_MASK) { case I8XX_GC_MODE1: kbytes = 1024; /* 1M preallocated memory */ break; case I8XX_GC_MODE3: kbytes = 8 * 1024; /* 8M preallocated memory */ break; default: kbytes = 0; /* an unexpected case */ } break; default: kbytes = 0; } return (kbytes); }
/*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); }
/* * audio1575_chip_init() * * Description: * This routine initializes the M1575 AC97 audio controller and the AC97 * codec. The AC97 codec registers are programmed from codec_shadow[]. * If we are not doing a restore, we initialize codec_shadow[], otherwise * we use the current values of shadow. This routine expects that the * PCI IO and Memory spaces have been mapped and enabled already. * Arguments: * audio1575_state_t *state The device's state structure * restore from codec_shadow[] * Returns: * DDI_SUCCESS The hardware was initialized properly * DDI_FAILURE The hardware couldn't be initialized properly */ static int audio1575_chip_init(audio1575_state_t *statep) { uint32_t ssr; uint32_t rtsr; uint32_t intrsr; int i; int j; #ifdef __sparc uint8_t clk_detect; ddi_acc_handle_t pcih; #endif clock_t ticks; /* * clear the interrupt control and status register * READ/WRITE/READ workaround required * for buggy hardware */ PUT32(M1575_INTRCR_REG, 0); (void) GET32(M1575_INTRCR_REG); intrsr = GET32(M1575_INTRSR_REG); PUT32(M1575_INTRSR_REG, (intrsr & M1575_INTR_MASK)); (void) GET32(M1575_INTRSR_REG); ticks = drv_usectohz(M1575_LOOP_CTR); /* * SADA only supports stereo, so we set the channel bits * to "00" to select 2 channels. * will also set the following: * * Disable double rate enable * no SPDIF output selected * 16 bit audio record mode * 16 bit pcm out mode * PCM Out 6 chan mode FL FR CEN BL BR LFE * PCM Out 2 channel mode (00) */ for (i = 0; i < M1575_LOOP_CTR; i++) { /* Reset the AC97 Codec and default to 2 channel 16 bit mode */ PUT32(M1575_SCR_REG, M1575_SCR_COLDRST); delay(ticks<<1); /* Read the System Status Reg */ ssr = GET32(M1575_SSR_REG); /* make sure and release the blocked reset bit */ if (ssr & M1575_SSR_RSTBLK) { SET32(M1575_INTFCR_REG, M1575_INTFCR_RSTREL); delay(ticks); /* Read the System Status Reg */ ssr = GET32(M1575_SSR_REG); /* make sure and release the blocked reset bit */ if (ssr & M1575_SSR_RSTBLK) { return (DDI_FAILURE); } /* Reset the controller */ PUT32(M1575_SCR_REG, M1575_SCR_COLDRST); delay(ticks); } /* according AC'97 spec, wait for codec reset */ for (j = 0; j < M1575_LOOP_CTR; j++) { if ((GET32(M1575_SCR_REG) & M1575_SCR_COLDRST) == 0) { break; } delay(ticks); } /* codec reset failed */ if (j >= M1575_LOOP_CTR) { audio_dev_warn(statep->adev, "failure to reset codec"); return (DDI_FAILURE); } /* * Wait for FACRDY First codec ready. The hardware can * provide the state of * codec ready bit on SDATA_IN[0] and as reflected in * the Recv Tag Slot Reg. */ rtsr = GET32(M1575_RTSR_REG); if (rtsr & M1575_RTSR_FACRDY) { break; } else { /* reset the status and wait for new status to set */ rtsr |= M1575_RTSR_FACRDY; PUT32(M1575_RTSR_REG, rtsr); drv_usecwait(10); } } /* if we could not reset the AC97 codec then report failure */ if (i >= M1575_LOOP_CTR) { audio_dev_warn(statep->adev, "no codec ready signal received"); return (DDI_FAILURE); } #ifdef __sparc /* Magic code from ULi to Turn on the AC_LINK clock */ pcih = statep->pcih; pci_config_put8(pcih, M1575_PCIACD_REG, 0); pci_config_put8(pcih, M1575_PCIACD_REG, 4); pci_config_put8(pcih, M1575_PCIACD_REG, 0); (void) pci_config_get8(pcih, M1575_PCIACD_REG); pci_config_put8(pcih, M1575_PCIACD_REG, 2); pci_config_put8(pcih, M1575_PCIACD_REG, 0); clk_detect = pci_config_get8(pcih, M1575_PCIACD_REG); if (clk_detect != 1) { audio_dev_warn(statep->adev, "No AC97 Clock Detected"); return (DDI_FAILURE); } #endif /* Magic code from Uli to Init FIFO1 and FIFO2 */ PUT32(M1575_FIFOCR1_REG, 0x81818181); PUT32(M1575_FIFOCR2_REG, 0x81818181); PUT32(M1575_FIFOCR3_REG, 0x81818181); /* Make sure that PCM in and PCM out are enabled */ SET32(M1575_INTFCR_REG, (M1575_INTFCR_PCMIENB | M1575_INTFCR_PCMOENB)); audio1575_dma_stop(statep, B_FALSE); return (DDI_SUCCESS); }
/* * ehci_attach: * * Description: Attach entry point is called by the Kernel. * Allocates resources for each EHCI host controller instance. * Initializes the EHCI Host Controller. * * Return : DDI_SUCCESS / DDI_FAILURE. */ static int ehci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int instance; ehci_state_t *ehcip = NULL; usba_hcdi_register_args_t hcdi_args; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: ehcip = ehci_obtain_state(dip); return (ehci_cpr_resume(ehcip)); default: return (DDI_FAILURE); } /* Get the instance and create soft state */ instance = ddi_get_instance(dip); if (ddi_soft_state_zalloc(ehci_statep, instance) != 0) { return (DDI_FAILURE); } ehcip = ddi_get_soft_state(ehci_statep, instance); if (ehcip == NULL) { return (DDI_FAILURE); } ehcip->ehci_flags = EHCI_ATTACH; ehcip->ehci_log_hdl = usb_alloc_log_hdl(dip, "ehci", &ehci_errlevel, &ehci_errmask, &ehci_instance_debug, 0); ehcip->ehci_flags |= EHCI_ZALLOC; /* Set host controller soft state to initialization */ ehcip->ehci_hc_soft_state = EHCI_CTLR_INIT_STATE; USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehcip = 0x%p", (void *)ehcip); /* Initialize the DMA attributes */ ehci_set_dma_attributes(ehcip); /* Save the dip and instance */ ehcip->ehci_dip = dip; ehcip->ehci_instance = instance; /* Initialize the DMA attributes */ ehci_create_stats(ehcip); /* Create the qtd and qh pools */ if (ehci_allocate_pools(ehcip) != DDI_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } /* Initialize the isochronous resources */ if (ehci_isoc_init(ehcip) != DDI_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } /* Map the registers */ if (ehci_map_regs(ehcip) != DDI_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } /* Get the ehci chip vendor and device id */ ehcip->ehci_vendor_id = pci_config_get16( ehcip->ehci_config_handle, PCI_CONF_VENID); ehcip->ehci_device_id = pci_config_get16( ehcip->ehci_config_handle, PCI_CONF_DEVID); ehcip->ehci_rev_id = pci_config_get8( ehcip->ehci_config_handle, PCI_CONF_REVID); /* Register interrupts */ if (ehci_register_intrs_and_init_mutex(ehcip) != DDI_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } mutex_enter(&ehcip->ehci_int_mutex); /* Initialize the controller */ if (ehci_init_ctlr(ehcip, EHCI_NORMAL_INITIALIZATION) != DDI_SUCCESS) { mutex_exit(&ehcip->ehci_int_mutex); (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } /* * At this point, the hardware will be okay. * Initialize the usba_hcdi structure */ ehcip->ehci_hcdi_ops = ehci_alloc_hcdi_ops(ehcip); mutex_exit(&ehcip->ehci_int_mutex); /* * Make this HCD instance known to USBA * (dma_attr must be passed for USBA busctl's) */ hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION; hcdi_args.usba_hcdi_register_dip = dip; hcdi_args.usba_hcdi_register_ops = ehcip->ehci_hcdi_ops; hcdi_args.usba_hcdi_register_dma_attr = &ehcip->ehci_dma_attr; /* * Priority and iblock_cookie are one and the same * (However, retaining hcdi_soft_iblock_cookie for now * assigning it w/ priority. In future all iblock_cookie * could just go) */ hcdi_args.usba_hcdi_register_iblock_cookie = (ddi_iblock_cookie_t)(uintptr_t)ehcip->ehci_intr_pri; if (usba_hcdi_register(&hcdi_args, 0) != DDI_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } ehcip->ehci_flags |= EHCI_USBAREG; mutex_enter(&ehcip->ehci_int_mutex); if ((ehci_init_root_hub(ehcip)) != USB_SUCCESS) { mutex_exit(&ehcip->ehci_int_mutex); (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } mutex_exit(&ehcip->ehci_int_mutex); /* Finally load the root hub driver */ if (ehci_load_root_hub_driver(ehcip) != USB_SUCCESS) { (void) ehci_cleanup(ehcip); return (DDI_FAILURE); } ehcip->ehci_flags |= EHCI_RHREG; /* Display information in the banner */ ddi_report_dev(dip); mutex_enter(&ehcip->ehci_int_mutex); /* Reset the ehci initialization flag */ ehcip->ehci_flags &= ~EHCI_ATTACH; /* Print the Host Control's Operational registers */ ehci_print_caps(ehcip); ehci_print_regs(ehcip); (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000); mutex_exit(&ehcip->ehci_int_mutex); USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehci_attach: dip = 0x%p done", (void *)dip); return (DDI_SUCCESS); }
/* * Save the configuration registers for cdip as a property * so that it persists after detach/uninitchild. */ int pci_save_config_regs(dev_info_t *dip) { ddi_acc_handle_t confhdl; pci_config_header_state_t *chsp; pci_cap_save_desc_t *pci_cap_descp; int ret; uint32_t i, ncaps, nwords; uint32_t *regbuf, *p; uint8_t *maskbuf; size_t maskbufsz, regbufsz, capbufsz; ddi_acc_hdl_t *hp; off_t offset = 0; uint8_t cap_ptr, cap_id; int pcie = 0; PMD(PMD_SX, ("pci_save_config_regs %s:%d\n", ddi_driver_name(dip), ddi_get_instance(dip))) if (pci_config_setup(dip, &confhdl) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d can't get config handle", ddi_driver_name(dip), ddi_get_instance(dip)); return (DDI_FAILURE); } /* * Determine if it is a pci express device. If it is, save entire * 4k config space treating it as a array of 32 bit integers. * If it is not, do it in a usual PCI way. */ cap_ptr = pci_config_get8(confhdl, PCI_BCNF_CAP_PTR); /* * Walk the capabilities searching for pci express capability */ while (cap_ptr != PCI_CAP_NEXT_PTR_NULL) { cap_id = pci_config_get8(confhdl, cap_ptr + PCI_CAP_ID); if (cap_id == PCI_CAP_ID_PCI_E) { pcie = 1; break; } cap_ptr = pci_config_get8(confhdl, cap_ptr + PCI_CAP_NEXT_PTR); } if (pcie) { /* PCI express device. Can have data in all 4k space */ regbuf = (uint32_t *)kmem_zalloc((size_t)PCIE_CONF_HDR_SIZE, KM_SLEEP); p = regbuf; /* * Allocate space for mask. * mask size is 128 bytes (4096 / 4 / 8 ) */ maskbufsz = (size_t)((PCIE_CONF_HDR_SIZE/ sizeof (uint32_t)) >> INDEX_SHIFT); maskbuf = (uint8_t *)kmem_zalloc(maskbufsz, KM_SLEEP); hp = impl_acc_hdl_get(confhdl); for (i = 0; i < (PCIE_CONF_HDR_SIZE / sizeof (uint32_t)); i++) { if (ddi_peek32(dip, (int32_t *)(hp->ah_addr + offset), (int32_t *)p) == DDI_SUCCESS) { /* it is readable register. set the bit */ maskbuf[i >> INDEX_SHIFT] |= (uint8_t)(1 << (i & BITMASK)); } p++; offset += sizeof (uint32_t); } if ((ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, SAVED_CONFIG_REGS_MASK, (uchar_t *)maskbuf, maskbufsz)) != DDI_PROP_SUCCESS) { cmn_err(CE_WARN, "couldn't create %s property while" "saving config space for %s@%d\n", SAVED_CONFIG_REGS_MASK, ddi_driver_name(dip), ddi_get_instance(dip)); } else if ((ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, SAVED_CONFIG_REGS, (uchar_t *)regbuf, (size_t)PCIE_CONF_HDR_SIZE)) != DDI_PROP_SUCCESS) { (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, SAVED_CONFIG_REGS_MASK); cmn_err(CE_WARN, "%s%d can't update prop %s", ddi_driver_name(dip), ddi_get_instance(dip), SAVED_CONFIG_REGS); } kmem_free(maskbuf, (size_t)maskbufsz); kmem_free(regbuf, (size_t)PCIE_CONF_HDR_SIZE); } else {
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); }
/* * agp_target_get_apsize() * * Description: * This function gets the AGP aperture size by reading the AGP aperture * size register. * Arguments: * softstate driver soft state pointer * * Return: * size The AGP aperture size in megabytes * 0 an unexpected error */ static size_t agp_target_get_apsize(agp_target_softstate_t *softstate) { off_t cap; uint16_t value; size_t size, regsize; ASSERT(softstate->tsoft_acaptr); cap = softstate->tsoft_acaptr; if ((softstate->tsoft_devid & VENDOR_ID_MASK) == INTEL_VENDOR_ID) { /* extend this value to 16 bit for later tests */ value = (uint16_t)pci_config_get8(softstate->tsoft_pcihdl, cap + AGP_CONF_APERSIZE) | AGP_APER_SIZE_MASK; } else { value = pci_config_get16(softstate->tsoft_pcihdl, cap + AGP_CONF_APERSIZE); } if (value & AGP_APER_128M_MASK) { switch (value & AGP_APER_128M_MASK) { case AGP_APER_4M: size = 4; /* 4M */ break; case AGP_APER_8M: size = 8; /* 8M */ break; case AGP_APER_16M: size = 16; /* 16M */ break; case AGP_APER_32M: size = 32; /* 32M */ break; case AGP_APER_64M: size = 64; /* 64M */ break; case AGP_APER_128M: size = 128; /* 128M */ break; default: size = 0; /* not true */ } } else { switch (value & AGP_APER_4G_MASK) { case AGP_APER_256M: size = 256; /* 256 M */ break; case AGP_APER_512M: size = 512; /* 512 M */ break; case AGP_APER_1024M: size = 1024; /* 1024 M */ break; case AGP_APER_2048M: size = 2048; /* 2048 M */ break; case AGP_APER_4G: size = 4096; /* 4096 M */ break; default: size = 0; /* not true */ } } /* * In some cases, there is no APSIZE register, so the size value * of 256M could be wrong. Check the value by reading the size of * the first register which was set in the PCI configuration space. */ if (size == 256) { if (ddi_dev_regsize(softstate->tsoft_dip, AGP_TARGET_BAR1, (off_t *)®size) == DDI_FAILURE) return (0); if (MB2BYTES(size) != regsize) { TARGETDB_PRINT2((CE_WARN, "APSIZE 256M doesn't match regsize %lx", regsize)); TARGETDB_PRINT2((CE_WARN, "Use regsize instead")); size = BYTES2MB(regsize); } } return (size); }
/*ARGSUSED*/ static int xen_uppc_translate_irq(dev_info_t *dip, int irqno) { char dev_type[16]; int dev_len, pci_irq, devid, busid; ddi_acc_handle_t cfg_handle; uchar_t ipin, iline; iflag_t intr_flag; if (dip == NULL) { XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: irqno = %d" " dip = NULL\n", irqno)); return (irqno); } if (!xen_uppc_enable_acpi) { return (irqno); } dev_len = sizeof (dev_type); if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(dip), DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type, &dev_len) != DDI_PROP_SUCCESS) { XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: irqno %d" " device %s instance %d no device_type\n", irqno, ddi_get_name(dip), ddi_get_instance(dip))); return (irqno); } if ((strcmp(dev_type, "pci") == 0) || (strcmp(dev_type, "pciex") == 0)) { /* pci device */ if (acpica_get_bdf(dip, &busid, &devid, NULL) != 0) return (irqno); if (pci_config_setup(dip, &cfg_handle) != DDI_SUCCESS) return (irqno); ipin = pci_config_get8(cfg_handle, PCI_CONF_IPIN) - PCI_INTA; iline = pci_config_get8(cfg_handle, PCI_CONF_ILINE); if (xen_uppc_acpi_translate_pci_irq(dip, busid, devid, ipin, &pci_irq, &intr_flag) == ACPI_PSM_SUCCESS) { XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: [ACPI] " "new irq %d old irq %d device %s, instance %d\n", pci_irq, irqno, ddi_get_name(dip), ddi_get_instance(dip))); /* * Make sure pci_irq is within range. * Otherwise, fall through and return irqno. */ if (pci_irq <= MAX_ISA_IRQ) { if (iline != pci_irq) { /* * Update the device's ILINE byte, * in case uppc_acpi_translate_pci_irq * has choosen a different pci_irq * than the BIOS has configured. * Some chipsets use the value in * ILINE to control interrupt routing, * in conflict with the PCI spec. */ pci_config_put8(cfg_handle, PCI_CONF_ILINE, pci_irq); } pci_config_teardown(&cfg_handle); return (pci_irq); } } pci_config_teardown(&cfg_handle); /* FALLTHRU to common case - returning irqno */ } else { /* non-PCI; assumes ISA-style edge-triggered */ psm_set_elcr(irqno, 0); /* set IRQ to ISA mode */ XEN_UPPC_VERBOSE_IRQ((CE_CONT, "!xVM_uppc: non-pci," "irqno %d device %s instance %d\n", irqno, ddi_get_name(dip), ddi_get_instance(dip))); } return (irqno); }
/* * 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); }
void t4_os_pci_read_cfg1(struct adapter *sc, int reg, uint8_t *val) { *val = pci_config_get8(sc->pci_regh, reg); }
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); }
static void ppb_create_ranges_prop(dev_info_t *dip, ddi_acc_handle_t config_handle) { uint32_t base, limit; ppb_ranges_t ranges[PPB_RANGE_LEN]; uint8_t io_base_lo, io_limit_lo; uint16_t io_base_hi, io_limit_hi, mem_base, mem_limit; int i = 0, rangelen = sizeof (ppb_ranges_t)/sizeof (int); io_base_lo = pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW); io_limit_lo = pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW); io_base_hi = pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI); io_limit_hi = pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI); mem_base = pci_config_get16(config_handle, PCI_BCNF_MEM_BASE); mem_limit = pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT); /* * Create ranges for IO space */ ranges[i].size_low = ranges[i].size_high = 0; ranges[i].parent_mid = ranges[i].child_mid = ranges[i].parent_high = 0; ranges[i].child_high = ranges[i].parent_high |= (PCI_REG_REL_M | PCI_ADDR_IO); base = PPB_16bit_IOADDR(io_base_lo); limit = PPB_16bit_IOADDR(io_limit_lo); /* * Check for 32-bit I/O support as per PCI-to-PCI Bridge Arch Spec */ if ((io_base_lo & 0xf) == PPB_32BIT_IO) { base = PPB_LADDR(base, io_base_hi); limit = PPB_LADDR(limit, io_limit_hi); } /* * Check if the bridge implements an I/O address range as per * PCI-to-PCI Bridge Arch Spec */ if ((io_base_lo != 0 || io_limit_lo != 0) && limit >= base) { ranges[i].parent_low = ranges[i].child_low = base; ranges[i].size_low = limit - base + PPB_IOGRAIN; i++; } /* * Create ranges for 32bit memory space */ base = PPB_32bit_MEMADDR(mem_base); limit = PPB_32bit_MEMADDR(mem_limit); ranges[i].size_low = ranges[i].size_high = 0; ranges[i].parent_mid = ranges[i].child_mid = ranges[i].parent_high = 0; ranges[i].child_high = ranges[i].parent_high |= (PCI_REG_REL_M | PCI_ADDR_MEM32); ranges[i].child_low = ranges[i].parent_low = base; if (limit >= base) { ranges[i].size_low = limit - base + PPB_MEMGRAIN; i++; } if (i) { (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges", (int *)ranges, i * rangelen); } }
/*ARGSUSED*/ static int ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { dev_info_t *root = ddi_root_node(); int instance; ppb_devstate_t *ppb; dev_info_t *pdip; ddi_acc_handle_t config_handle; char *bus; switch (cmd) { case DDI_ATTACH: /* * Make sure the "device_type" property exists. */ (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", "pci"); /* * Allocate and get soft state structure. */ instance = ddi_get_instance(devi); if (ddi_soft_state_zalloc(ppb_state, instance) != DDI_SUCCESS) return (DDI_FAILURE); ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state, instance); ppb->dip = devi; mutex_init(&ppb->ppb_mutex, NULL, MUTEX_DRIVER, NULL); ppb->ppb_soft_state = PCI_SOFT_STATE_CLOSED; if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) { mutex_destroy(&ppb->ppb_mutex); ddi_soft_state_free(ppb_state, instance); return (DDI_FAILURE); } ppb_pwr_setup(ppb, devi); if (PM_CAPABLE(ppb->ppb_pwr_p)) { mutex_enter(&ppb->ppb_pwr_p->pwr_mutex); /* * Before reading config registers, make sure power is * on, and remains on. */ ppb->ppb_pwr_p->pwr_fp++; pci_pwr_change(ppb->ppb_pwr_p, ppb->ppb_pwr_p->current_lvl, pci_pwr_new_lvl(ppb->ppb_pwr_p)); } ppb->ppb_cache_line_size = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ); ppb->ppb_latency_timer = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER); /* * Check whether the "ranges" property is present. * Otherwise create the ranges property by reading * the configuration registers */ if (ddi_prop_exists(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, "ranges") == 0) { ppb_create_ranges_prop(devi, config_handle); } pci_config_teardown(&config_handle); if (PM_CAPABLE(ppb->ppb_pwr_p)) { ppb->ppb_pwr_p->pwr_fp--; pci_pwr_change(ppb->ppb_pwr_p, ppb->ppb_pwr_p->current_lvl, pci_pwr_new_lvl(ppb->ppb_pwr_p)); mutex_exit(&ppb->ppb_pwr_p->pwr_mutex); } ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO; for (pdip = ddi_get_parent(ppb->dip); pdip && (pdip != root) && (ppb->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV); pdip = ddi_get_parent(pdip)) { if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, "device_type", &bus) != DDI_PROP_SUCCESS) break; if (strcmp(bus, "pciex") == 0) ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCIE_DEV; ddi_prop_free(bus); } /* * Initialize hotplug support on this bus. */ if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) if (pcie_init(devi, NULL) != DDI_SUCCESS) { (void) ppb_detach(devi, DDI_DETACH); return (DDI_FAILURE); } else ppb_init_hotplug(ppb); DEBUG1(DBG_ATTACH, devi, "ppb_attach(): this nexus %s hotplug slots\n", ppb->hotplug_capable == B_TRUE ? "has":"has no"); ppb_fm_init(ppb); ddi_report_dev(devi); return (DDI_SUCCESS); case DDI_RESUME: /* * Get the soft state structure for the bridge. */ ppb = (ppb_devstate_t *) ddi_get_soft_state(ppb_state, ddi_get_instance(devi)); pci_pwr_resume(devi, ppb->ppb_pwr_p); return (DDI_SUCCESS); } return (DDI_FAILURE); }
/* * Controller specific initialization */ uint_t sil3xxx_init_controller(dev_info_t *dip, /* LINTED */ ushort_t vendor_id, ushort_t device_id) { ddi_acc_handle_t pci_conf_handle; /* pci config space handle */ uint8_t cache_lnsz, frrc = 0; uint32_t fifo_cnt_ctl; int ports, i; #ifdef DEBUG /* LINTED */ ushort_t sfiscfg_val; #endif /* * Sil3114, Sil3512, Sil3112 * We want to perform this initialization only once per entire * pciide controller (all channels) */ if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_get_parent(dip), DDI_PROP_DONTPASS, "sil3xxx-initialized")) { return (TRUE); } if (pci_config_setup(ddi_get_parent(dip), &pci_conf_handle) != DDI_SUCCESS) { cmn_err(CE_WARN, "sil3xxx_init_controller: Can't do pci_config_setup\n"); return (FALSE); } /* * Sil3114/3512/3112 incorrectly change between MR and back to * MRM for same transaction, which violates the PCI spec and can * lead to incorrect data reads. The workaround * is to set bits 2:0 in the FIFO count and control register so * that its value, a multiple of 32 bytes starting at 32, not 0, * is greater or equal to the cacheline size, a multiple of 4 * bytes. This will prevent any reads until the FIFO free space * is greater than a cacheline size, ensuring only MRM is issued. */ cache_lnsz = pci_config_get8(pci_conf_handle, PCI_CONF_CACHE_LINESZ); /* * The cache line is specified in 32-bit words, so multiply by 4 * to get bytes. Then divide by 32 bytes, the granularity of the * FIFO control bits 2:0. Add 1 if there is any remainder to * account for a partial 32-byte block, then subtract 1 since for * FIFO controls bits 2:0, 0 corresponds to 32, 1 corresponds to * 64, and so on. The calculation is expanded for clarity. */ if (cache_lnsz != 0) { frrc = (cache_lnsz * 4 / 32) + (((cache_lnsz * 4) % 32) ? 1 : 0) - 1; } if (device_id == SIL3114_DEVICE_ID) { ports = 4; } else { ports = 2; } /* * The following BAR5 registers are accessed via an indirect register * in the PCI configuration space rather than mapping BAR5. */ for (i = 0; i < ports; i++) { GET_BAR5_INDIRECT(pci_conf_handle, fifocntctl[i], fifo_cnt_ctl); fifo_cnt_ctl = (fifo_cnt_ctl & ~0x7) | (frrc & 0x7); PUT_BAR5_INDIRECT(pci_conf_handle, fifocntctl[i], fifo_cnt_ctl); /* * Correct default setting for FIS0cfg */ #ifdef DEBUG GET_BAR5_INDIRECT(pci_conf_handle, sfiscfg[i], sfiscfg_val); ADBG_WARN(("sil3xxx_init_controller: old val SFISCfg " "ch%d: %x\n", i, sfiscfg_val)); #endif PUT_BAR5_INDIRECT(pci_conf_handle, sfiscfg[i], SFISCFG_ERRATA); #ifdef DEBUG GET_BAR5_INDIRECT(pci_conf_handle, sfiscfg[i], sfiscfg_val); ADBG_WARN(("sil3xxx_init_controller: new val SFISCfg " "ch%d: %x\n", i, sfiscfg_val)); #endif } /* Now tear down the pci config setup */ pci_config_teardown(&pci_conf_handle); /* Create property indicating that initialization was done */ (void) ddi_prop_update_int(DDI_DEV_T_NONE, ddi_get_parent(dip), "sil3xxx-initialized", 1); return (TRUE); }
void pciconfig_dump(void *instance) { struct e1000g *Adapter = (struct e1000g *)instance; ddi_acc_handle_t handle; uint8_t cap_ptr; uint8_t next_ptr; off_t offset; handle = Adapter->osdep.cfg_handle; e1000g_log(Adapter, CE_CONT, "Begin dump PCI config space\n"); e1000g_log(Adapter, CE_CONT, "PCI_CONF_VENID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_VENID)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_DEVID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_DEVID)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_COMMAND:\t0x%x\n", pci_config_get16(handle, PCI_CONF_COMM)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_STATUS:\t0x%x\n", pci_config_get16(handle, PCI_CONF_STAT)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_REVID:\t0x%x\n", pci_config_get8(handle, PCI_CONF_REVID)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_PROG_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_PROGCLASS)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_SUB_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_SUBCLASS)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_BAS_CLASS:\t0x%x\n", pci_config_get8(handle, PCI_CONF_BASCLASS)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_CACHE_LINESZ:\t0x%x\n", pci_config_get8(handle, PCI_CONF_CACHE_LINESZ)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_LATENCY_TIMER:\t0x%x\n", pci_config_get8(handle, PCI_CONF_LATENCY_TIMER)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_HEADER_TYPE:\t0x%x\n", pci_config_get8(handle, PCI_CONF_HEADER)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_BIST:\t0x%x\n", pci_config_get8(handle, PCI_CONF_BIST)); pciconfig_bar(Adapter, PCI_CONF_BASE0, "PCI_CONF_BASE0"); pciconfig_bar(Adapter, PCI_CONF_BASE1, "PCI_CONF_BASE1"); pciconfig_bar(Adapter, PCI_CONF_BASE2, "PCI_CONF_BASE2"); pciconfig_bar(Adapter, PCI_CONF_BASE3, "PCI_CONF_BASE3"); pciconfig_bar(Adapter, PCI_CONF_BASE4, "PCI_CONF_BASE4"); pciconfig_bar(Adapter, PCI_CONF_BASE5, "PCI_CONF_BASE5"); e1000g_log(Adapter, CE_CONT, "PCI_CONF_CIS:\t0x%x\n", pci_config_get32(handle, PCI_CONF_CIS)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_SUBVENID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_SUBVENID)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_SUBSYSID:\t0x%x\n", pci_config_get16(handle, PCI_CONF_SUBSYSID)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_ROM:\t0x%x\n", pci_config_get32(handle, PCI_CONF_ROM)); cap_ptr = pci_config_get8(handle, PCI_CONF_CAP_PTR); e1000g_log(Adapter, CE_CONT, "PCI_CONF_CAP_PTR:\t0x%x\n", cap_ptr); e1000g_log(Adapter, CE_CONT, "PCI_CONF_ILINE:\t0x%x\n", pci_config_get8(handle, PCI_CONF_ILINE)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_IPIN:\t0x%x\n", pci_config_get8(handle, PCI_CONF_IPIN)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_MIN_G:\t0x%x\n", pci_config_get8(handle, PCI_CONF_MIN_G)); e1000g_log(Adapter, CE_CONT, "PCI_CONF_MAX_L:\t0x%x\n", pci_config_get8(handle, PCI_CONF_MAX_L)); /* Power Management */ offset = cap_ptr; e1000g_log(Adapter, CE_CONT, "PCI_PM_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset)); next_ptr = pci_config_get8(handle, offset + 1); e1000g_log(Adapter, CE_CONT, "PCI_PM_NEXT_PTR:\t0x%x\n", next_ptr); e1000g_log(Adapter, CE_CONT, "PCI_PM_CAP:\t0x%x\n", pci_config_get16(handle, offset + PCI_PMCAP)); e1000g_log(Adapter, CE_CONT, "PCI_PM_CSR:\t0x%x\n", pci_config_get16(handle, offset + PCI_PMCSR)); e1000g_log(Adapter, CE_CONT, "PCI_PM_CSR_BSE:\t0x%x\n", pci_config_get8(handle, offset + PCI_PMCSR_BSE)); e1000g_log(Adapter, CE_CONT, "PCI_PM_DATA:\t0x%x\n", pci_config_get8(handle, offset + PCI_PMDATA)); /* MSI Configuration */ offset = next_ptr; e1000g_log(Adapter, CE_CONT, "PCI_MSI_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset)); next_ptr = pci_config_get8(handle, offset + 1); e1000g_log(Adapter, CE_CONT, "PCI_MSI_NEXT_PTR:\t0x%x\n", next_ptr); e1000g_log(Adapter, CE_CONT, "PCI_MSI_CTRL:\t0x%x\n", pci_config_get16(handle, offset + PCI_MSI_CTRL)); e1000g_log(Adapter, CE_CONT, "PCI_MSI_ADDR:\t0x%x\n", pci_config_get32(handle, offset + PCI_MSI_ADDR_OFFSET)); e1000g_log(Adapter, CE_CONT, "PCI_MSI_ADDR_HI:\t0x%x\n", pci_config_get32(handle, offset + 0x8)); e1000g_log(Adapter, CE_CONT, "PCI_MSI_DATA:\t0x%x\n", pci_config_get16(handle, offset + 0xC)); /* PCI Express Configuration */ offset = next_ptr; e1000g_log(Adapter, CE_CONT, "PCIE_CAP_ID:\t0x%x\n", pci_config_get8(handle, offset + PCIE_CAP_ID)); next_ptr = pci_config_get8(handle, offset + PCIE_CAP_NEXT_PTR); e1000g_log(Adapter, CE_CONT, "PCIE_CAP_NEXT_PTR:\t0x%x\n", next_ptr); e1000g_log(Adapter, CE_CONT, "PCIE_PCIECAP:\t0x%x\n", pci_config_get16(handle, offset + PCIE_PCIECAP)); e1000g_log(Adapter, CE_CONT, "PCIE_DEVCAP:\t0x%x\n", pci_config_get32(handle, offset + PCIE_DEVCAP)); e1000g_log(Adapter, CE_CONT, "PCIE_DEVCTL:\t0x%x\n", pci_config_get16(handle, offset + PCIE_DEVCTL)); e1000g_log(Adapter, CE_CONT, "PCIE_DEVSTS:\t0x%x\n", pci_config_get16(handle, offset + PCIE_DEVSTS)); e1000g_log(Adapter, CE_CONT, "PCIE_LINKCAP:\t0x%x\n", pci_config_get32(handle, offset + PCIE_LINKCAP)); e1000g_log(Adapter, CE_CONT, "PCIE_LINKCTL:\t0x%x\n", pci_config_get16(handle, offset + PCIE_LINKCTL)); e1000g_log(Adapter, CE_CONT, "PCIE_LINKSTS:\t0x%x\n", pci_config_get16(handle, offset + PCIE_LINKSTS)); }