int32_t i_ddi_set_intr_weight(dev_info_t *dip, int32_t weight) { int32_t oweight; oweight = i_ddi_get_intr_weight(dip); if ((weight > 0) && (oweight != weight)) (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "ddi-intr-weight", weight); return (oweight); }
/* * vdds_new_niu_node -- callback function to create a new NIU Hybrid node. */ static int vdds_new_niu_node(dev_info_t *dip, void *arg, uint_t flags) { vdds_cb_arg_t *cba = (vdds_cb_arg_t *)arg; char *compat[] = { "SUNW,niusl" }; uint8_t macaddrbytes[ETHERADDRL]; int interrupts[VDDS_MAX_VRINTRS]; vdds_ranges_t *prng; vdds_ranges_t *prp; vdds_reg_t reg; dev_info_t *pdip; uint64_t start; uint64_t size; int prnglen; int nintr = 0; int nrng; int rnum; int rv; DBG1(NULL, "Called dip=0x%p flags=0x%X", dip, flags); pdip = ddi_get_parent(dip); if (pdip == NULL) { DWARN(NULL, "Failed to get parent dip(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "network" property */ if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "name", "network") != DDI_SUCCESS) { DERR(NULL, "Failed to create name property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* * create "niutype" property, it is set to n2niu to * indicate NIU Hybrid node. */ if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "niutype", "n2niu") != DDI_SUCCESS) { DERR(NULL, "Failed to create niuopmode property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "compatible" property */ if (ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible", compat, 1) != DDI_SUCCESS) { DERR(NULL, "Failed to create compatible property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "device_type" property */ if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "device_type", "network") != DDI_SUCCESS) { DERR(NULL, "Failed to create device_type property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "reg" property */ if (vdds_hv_niu_vr_getinfo(HVCOOKIE(cba->cookie), &start, &size) != H_EOK) { DERR(NULL, "Failed to get vrinfo for cookie(0x%lX)", cba->cookie); return (DDI_WALK_ERROR); } reg.addr_hi = HVCOOKIE(cba->cookie); reg.addr_lo = 0; reg.size_hi = 0; reg.size_lo = size; if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", (int *)®, sizeof (reg) / sizeof (int)) != DDI_SUCCESS) { DERR(NULL, "Failed to create reg property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* * Modify the parent's ranges property to map the "reg" property * of the new child. */ if ((rv = ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, "ranges", (caddr_t)&prng, &prnglen)) != DDI_SUCCESS) { DERR(NULL, "Failed to get parent's ranges property(pdip=0x%p) rv=%d", pdip, rv); return (DDI_WALK_ERROR); } nrng = prnglen/(sizeof (vdds_ranges_t)); /* * First scan all ranges to see if a range corresponding * to this virtual NIU exists already. */ for (rnum = 0; rnum < nrng; rnum++) { prp = &prng[rnum]; if (prp->child_hi == HVCOOKIE(cba->cookie)) { break; } } if (rnum == nrng) { /* Now to try to find an empty range */ for (rnum = 0; rnum < nrng; rnum++) { prp = &prng[rnum]; if (prp->child_hi == 0) { break; } } } if (rnum == nrng) { DERR(NULL, "No free ranges entry found"); return (DDI_WALK_ERROR); } /* * child_hi will have HV cookie as HV cookie is more like * a port in the HybridIO. */ prp->child_hi = HVCOOKIE(cba->cookie); prp->child_lo = 0; prp->parent_hi = 0x80000000 | (start >> 32); prp->parent_lo = start & 0x00000000FFFFFFFF; prp->size_hi = (size >> 32); prp->size_lo = size & 0x00000000FFFFFFFF; if (ndi_prop_update_int_array(DDI_DEV_T_NONE, pdip, "ranges", (int *)prng, (nrng * 6)) != DDI_SUCCESS) { DERR(NULL, "Failed to update parent ranges prop(pdip=0x%p)", pdip); return (DDI_WALK_ERROR); } kmem_free((void *)prng, prnglen); vnet_macaddr_ultostr(cba->macaddr, macaddrbytes); /* * create "local-mac-address" property, this will be same as * the vnet's mac-address. */ if (ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, "local-mac-address", macaddrbytes, ETHERADDRL) != DDI_SUCCESS) { DERR(NULL, "Failed to update mac-addresses property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } rv = vdds_get_interrupts(cba->cookie, rnum, interrupts, &nintr); if (rv != 0) { DERR(NULL, "Failed to get interrupts for cookie=0x%lx", cba->cookie); return (DDI_WALK_ERROR); } /* create "interrupts" property */ if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "interrupts", interrupts, nintr) != DDI_SUCCESS) { DERR(NULL, "Failed to update interrupts property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "max_frame_size" property */ if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "max-frame-size", cba->max_frame_size) != DDI_SUCCESS) { DERR(NULL, "Failed to update max-frame-size property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } cba->dip = dip; DBG1(NULL, "Returning dip=0x%p", dip); return (DDI_WALK_TERMINATE); }
/* * vdds_new_nexus_node -- callback function to set all the properties * a new NIU nexus node. */ static int vdds_new_nexus_node(dev_info_t *dip, void *arg, uint_t flags) { vdds_cb_arg_t *cba = (vdds_cb_arg_t *)arg; char *compat[] = { "SUNW,niumx" }; vdds_ranges_t *rangesp; vdds_reg_t reg; uint64_t nranges; int n; DBG1(NULL, "Called dip=0x%p, flags=0x%X", dip, flags); /* create "niu" property */ if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "name", "niu") != DDI_SUCCESS) { DERR(NULL, "Failed to create name property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "compatible" property */ if (ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible", compat, 1) != DDI_SUCCESS) { DERR(NULL, "Failed to create compatible property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* create "device_type" property */ if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "device_type", "sun4v") != DDI_SUCCESS) { DERR(NULL, "Failed to create device_type property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* * create "reg" property. The first 28 bits of * 'addr_hi' are NIU cfg_handle, the 0xc in 28-31 bits * indicates non-cacheable config. */ reg.addr_hi = 0xc0000000 | NIUCFGHDL(cba->cookie); reg.addr_lo = 0; reg.size_hi = 0; reg.size_lo = 0; if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", (int *)®, sizeof (reg)/sizeof (int)) != DDI_SUCCESS) { DERR(NULL, "Failed to create reg property(dip=0x%p)", dip); return (DDI_WALK_ERROR); } /* * Create VDDS_MAX_RANGES so that they are already in place * before the children are created. While creating the child * we just modify one of this ranges entries. */ nranges = VDDS_MAX_RANGES; /* One range for each VR */ rangesp = (vdds_ranges_t *)kmem_zalloc( (sizeof (vdds_ranges_t) * nranges), KM_SLEEP); for (n = 0; n < nranges; n++) { /* zero all child_hi/lo */ rangesp[n].child_hi = 0; rangesp[n].child_lo = 0; } if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges", (int *)rangesp, (nranges * 6)) != DDI_SUCCESS) { DERR(NULL, "Failed to create ranges property(dip=0x%p)", dip); kmem_free(rangesp, (sizeof (vdds_ranges_t) * nranges)); return (DDI_WALK_ERROR); } /* create "#size-cells" property */ if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "#size-cells", 2) != DDI_SUCCESS) { DERR(NULL, "Failed to create #size-cells property(dip=0x%p)", dip); kmem_free(rangesp, (sizeof (vdds_ranges_t) * nranges)); return (DDI_WALK_ERROR); } /* create "#address-cells" property */ if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "#address-cells", 2) != DDI_SUCCESS) { DERR(NULL, "Failed to create #address-cells prop(dip=0x%p)", dip); kmem_free(rangesp, (sizeof (vdds_ranges_t) * nranges)); return (DDI_WALK_ERROR); } kmem_free(rangesp, (sizeof (vdds_ranges_t) * nranges)); cba->dip = dip; DBG1(NULL, "Returning (dip=0x%p)", dip); return (DDI_WALK_TERMINATE); }
static ACPI_STATUS acpidev_cpu_init(acpidev_walk_info_t *infop) { int count; uint32_t pxmid; dev_info_t *dip; ACPI_HANDLE hdl; char unitaddr[64]; char **compatpp; static char *compatible[] = { ACPIDEV_HID_PROCESSOR, ACPIDEV_TYPE_CPU, "cpu" }; ASSERT(infop != NULL); dip = infop->awi_dip; hdl = infop->awi_hdl; /* Create "apic_id", "processor_id" and "proximity_id" properties. */ if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, ACPIDEV_PROP_NAME_PROCESSOR_ID, infop->awi_scratchpad[0]) != NDI_SUCCESS) { cmn_err(CE_WARN, "!acpidev: failed to set processor_id property for %s.", infop->awi_name); return (AE_ERROR); } if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, ACPIDEV_PROP_NAME_LOCALAPIC_ID, infop->awi_scratchpad[1]) != NDI_SUCCESS) { cmn_err(CE_WARN, "!acpidev: failed to set apic_id property for %s.", infop->awi_name); return (AE_ERROR); } if (ACPI_SUCCESS(acpidev_cpu_get_proximity_id(infop->awi_hdl, infop->awi_scratchpad[1], &pxmid))) { if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, ACPIDEV_PROP_NAME_PROXIMITY_ID, pxmid) != NDI_SUCCESS) { cmn_err(CE_WARN, "!acpidev: failed to set proximity id " "property for %s.", infop->awi_name); return (AE_ERROR); } } /* Set "compatible" property for CPU dip */ count = sizeof (compatible) / sizeof (compatible[0]); if (infop->awi_info->Type == ACPI_TYPE_PROCESSOR) { compatpp = compatible; } else if (infop->awi_info->Type == ACPI_TYPE_DEVICE) { /* * skip first item for pseudo processor HID. * acpidev_set_compatible() will handle HID/CID for CPU device. */ compatpp = &compatible[1]; count--; } else { return (AE_BAD_PARAMETER); } if (ACPI_FAILURE(acpidev_set_compatible(infop, compatpp, count))) { return (AE_ERROR); } /* * Set device unit-address property. * First try to generate meaningful unit address from _UID, * then use Processor Id if that fails. */ if ((infop->awi_info->Valid & ACPI_VALID_UID) == 0 || acpidev_generate_unitaddr(infop->awi_info->UniqueId.String, ACPIDEV_ARRAY_PARAM(acpidev_cpu_uid_formats), unitaddr, sizeof (unitaddr)) == NULL) { (void) snprintf(unitaddr, sizeof (unitaddr), "%u", (uint32_t)infop->awi_scratchpad[0]); } if (ACPI_FAILURE(acpidev_set_unitaddr(infop, NULL, 0, unitaddr))) { return (AE_ERROR); } /* * Build binding information for CPUs. */ if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE || infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE || infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) { if (ACPI_FAILURE(acpica_add_processor_to_map( infop->awi_scratchpad[0], hdl, infop->awi_scratchpad[1]))) { cmn_err(CE_WARN, "!acpidev: failed to bind processor " "id/object handle for %s.", infop->awi_name); return (AE_ERROR); } } else { ACPIDEV_DEBUG(CE_WARN, "!acpidev: unknown operation type %u in acpidev_cpu_init.", infop->awi_op_type); return (AE_BAD_PARAMETER); } return (AE_OK); }
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); }
/* * nx1394_bus_ctl() * This routine implements nexus bus ctl operations. Of importance are * DDI_CTLOPS_REPORTDEV, DDI_CTLOPS_INITCHILD, DDI_CTLOPS_UNINITCHILD * and DDI_CTLOPS_POWER. For DDI_CTLOPS_INITCHILD, it tries to lookup * reg property on the child node and builds and sets the name * (name is of the form GGGGGGGGGGGGGGGG[,AAAAAAAAAAAA], where * GGGGGGGGGGGGGGGG is the GUID and AAAAAAAAAAAA is the optional unit * address). */ static int nx1394_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg, void *result) { int status; TNF_PROBE_0_DEBUG(nx1394_bus_ctl_enter, S1394_TNF_SL_NEXUS_STACK, ""); switch (op) { case DDI_CTLOPS_REPORTDEV: { dev_info_t *pdip = ddi_get_parent(rdip); cmn_err(CE_CONT, "?%s%d at %s%d", ddi_node_name(rdip), ddi_get_instance(rdip), ddi_node_name(pdip), ddi_get_instance(pdip)); TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, ""); return (DDI_SUCCESS); } case DDI_CTLOPS_INITCHILD: { dev_info_t *ocdip, *cdip = (dev_info_t *)arg; dev_info_t *pdip = ddi_get_parent(cdip); int reglen, i; uint32_t *regptr; char addr[MAXNAMELEN]; TNF_PROBE_1(nx1394_bus_ctl_init_child, S1394_TNF_SL_HOTPLUG_STACK, "", tnf_opaque, dip, cdip); i = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS, "reg", (int **)®ptr, (uint_t *)®len); if (i != DDI_PROP_SUCCESS) { cmn_err(CE_NOTE, "!%s(%d): \"reg\" property not found", ddi_node_name(cdip), ddi_get_instance(cdip)); TNF_PROBE_2(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg, "Reg property not found", tnf_int, reason, i); TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "initchild"); return (DDI_NOT_WELL_FORMED); } ASSERT(reglen != 0); /* * addr is of the format GGGGGGGGGGGGGGGG[,AAAAAAAAAAAA] */ if (regptr[2] || regptr[3]) { (void) sprintf(addr, "%08x%08x,%04x%08x", regptr[0], regptr[1], regptr[2], regptr[3]); } else { (void) sprintf(addr, "%08x%08x", regptr[0], regptr[1]); } ddi_prop_free(regptr); ddi_set_name_addr(cdip, addr); /* * Check for a node with the same name & addr as the current * node. If such a node exists, return failure. */ if ((ocdip = ndi_devi_find(pdip, ddi_node_name(cdip), addr)) != NULL && ocdip != cdip) { cmn_err(CE_NOTE, "!%s(%d): Duplicate dev_info node found %s@%s", ddi_node_name(cdip), ddi_get_instance(cdip), ddi_node_name(ocdip), addr); TNF_PROBE_1(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg, "Duplicate nodes"); TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "initchild"); ddi_set_name_addr(cdip, NULL); return (DDI_NOT_WELL_FORMED); } /* * If HAL (parent dip) has "active-dma-flush" property, then * add property to child as well. Workaround for active * context flushing bug in Schizo rev 2.1 and 2.2. */ if (ddi_prop_exists(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, "active-dma-flush") != 0) { status = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "active-dma-flush", 1); if (status != NDI_SUCCESS) { cmn_err(CE_NOTE, "!%s(%d): Unable to add " "\"active-dma-flush\" property", ddi_node_name(cdip), ddi_get_instance(cdip)); TNF_PROBE_1(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg, "Unable to add \"active-dma-flush\" " "property"); TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "initchild"); ddi_set_name_addr(cdip, NULL); return (DDI_NOT_WELL_FORMED); } } TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "initchild"); return (DDI_SUCCESS); } case DDI_CTLOPS_UNINITCHILD: { ddi_prop_remove_all((dev_info_t *)arg); ddi_set_name_addr((dev_info_t *)arg, NULL); TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "uninitchild"); return (DDI_SUCCESS); } case DDI_CTLOPS_IOMIN: { status = ddi_ctlops(dip, rdip, op, arg, result); TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "iomin"); return (status); } case DDI_CTLOPS_POWER: { return (DDI_SUCCESS); } /* * These ops correspond to functions that "shouldn't" be called * by a 1394 client driver. */ case DDI_CTLOPS_DMAPMAPC: case DDI_CTLOPS_REPORTINT: case DDI_CTLOPS_REGSIZE: case DDI_CTLOPS_NREGS: case DDI_CTLOPS_SIDDEV: case DDI_CTLOPS_SLAVEONLY: case DDI_CTLOPS_AFFINITY: case DDI_CTLOPS_POKE: case DDI_CTLOPS_PEEK: { cmn_err(CE_CONT, "!%s(%d): invalid op (%d) from %s(%d)", ddi_node_name(dip), ddi_get_instance(dip), op, ddi_node_name(rdip), ddi_get_instance(rdip)); TNF_PROBE_2(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg, "invalid op", tnf_int, op, op); TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, ""); return (DDI_FAILURE); } /* * Everything else (e.g. PTOB/BTOP/BTOPR requests) we pass up */ default: { status = ddi_ctlops(dip, rdip, op, arg, result); TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK, ""); return (status); } } }
boolean_t check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, uchar_t func, boolean_t *slot_valid, ushort_t *slot_number, ushort_t *is_pci_bridge) { boolean_t found_pciex = B_FALSE; ushort_t cap; ushort_t capsp; ushort_t cap_count = PCI_CAP_MAX_PTR; ushort_t status; uint32_t slot_cap; *slot_valid = B_FALSE; status = (*pci_getw_func)(bus, dev, func, PCI_CONF_STAT); if (!(status & PCI_STAT_CAP)) return (B_FALSE); capsp = (*pci_getb_func)(bus, dev, func, PCI_CONF_CAP_PTR); while (cap_count-- && capsp >= PCI_CAP_PTR_OFF) { capsp &= PCI_CAP_PTR_MASK; cap = (*pci_getb_func)(bus, dev, func, capsp); if (cap == PCI_CAP_ID_PCI_E) { #ifdef DEBUG if (pci_boot_debug) cmn_err(CE_CONT, "PCI-Express (%x,%x,%x) " "capability found\n", bus, dev, func); #endif /* DEBUG */ status = (*pci_getw_func)(bus, dev, func, capsp + 2); /* * See section 7.8.2 of PCI-Express Base Spec v1.0a * for Device/Port Type. * PCIE_PCIECAP_DEV_TYPE_PCIE2PCI implies that the * device is a PCIe2PCI bridge */ *is_pci_bridge = ((status & PCIE_PCIECAP_DEV_TYPE_MASK) == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ? 1 : 0; /* * Check for "Slot Implemented" bit * PCIE_PCIECAP_SLOT_IMPL implies that. */ if (status & PCIE_PCIECAP_SLOT_IMPL) { /* offset 14h is Slot Cap Register */ slot_cap = (*pci_getl_func)(bus, dev, func, capsp + PCIE_SLOTCAP); *slot_valid = B_TRUE; *slot_number = PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap); /* Is PCI Express HotPlug capability set? */ if (cdip && (slot_cap & PCIE_SLOTCAP_HP_CAPABLE)) { (void) ndi_prop_update_int( DDI_DEV_T_NONE, cdip, "pci-hotplug-type", INBAND_HPC_PCIE); } } found_pciex = B_TRUE; } if (cdip && (cap == PCI_CAP_ID_PCI_HOTPLUG)) { (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "pci-hotplug-type", INBAND_HPC_SHPC); } capsp = (*pci_getb_func)(bus, dev, func, capsp + PCI_CAP_NEXT_PTR); } return (found_pciex); }