Ejemplo n.º 1
0
static void
ppb_removechild(dev_info_t *dip)
{
	ppb_devstate_t *ppb;

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(dip)));

	if (PM_CAPABLE(ppb->ppb_pwr_p)) {

		DEBUG2(DBG_PWR, ddi_get_parent(dip),
		    "UNINITCHILD: removing pwr_info for %s@%s\n",
		    ddi_node_name(dip), ddi_get_name_addr(dip));
		pci_pwr_rm_info(ppb->ppb_pwr_p, dip);
	}

	ddi_set_name_addr(dip, NULL);

	/*
	 * Strip the node to properly convert it back to prototype form
	 */
	ddi_remove_minor_node(dip, NULL);

	impl_rem_dev_props(dip);
}
Ejemplo n.º 2
0
static dev_info_t *
get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip)
{
	dev_info_t *cdip = rdip;

	for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip))
		;

	return (cdip);
}
Ejemplo n.º 3
0
int
is_pseudo_device(dev_info_t *dip)
{
	dev_info_t	*pdip;

	for (pdip = ddi_get_parent(dip); pdip && pdip != ddi_root_node();
	    pdip = ddi_get_parent(pdip)) {
		if (strcmp(ddi_get_name(pdip), DEVI_PSEUDO_NEXNAME) == 0)
			return (1);
	}
	return (0);
}
Ejemplo n.º 4
0
static int
fco_parent(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
{
	fc_phandle_t h;
	dev_info_t *dip;

	if (fc_cell2int(cp->nargs) != 1)
		return (fc_syntax_error(cp, "nargs must be 1"));

	if (fc_cell2int(cp->nresults) < 1)
		return (fc_syntax_error(cp, "nresults must be > 0"));

	/*
	 * Make sure this is a handle we gave out ...
	 */
	h = fc_cell2phandle(fc_arg(cp, 0));
	if ((dip = fc_phandle_to_dip(fc_handle_to_phandle_head(rp), h)) == NULL)
		return (fc_priv_error(cp, "unknown handle"));

	/*
	 * Find the parent and if there is one, return it ...
	 */
	dip = ddi_get_parent(dip);
	h = 0;
	if (dip != NULL)
		h = fc_dip_to_phandle(fc_handle_to_phandle_head(rp), dip);

	cp->nresults = fc_int2cell(1);
	fc_result(cp, 0) = fc_phandle2cell(h);
	return (fc_success_op(ap, rp, cp));
}
Ejemplo n.º 5
0
static int vboxUSBMonSolarisResetDevice(char *pszDevicePath, bool fReattach)
{
    int rc = VERR_GENERAL_FAILURE;

    LogFunc((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: pszDevicePath=%s fReattach=%d\n", pszDevicePath, fReattach));

    /*
     * Try grabbing the dev_info_t.
     */
    dev_info_t *pDeviceInfo = e_ddi_hold_devi_by_path(pszDevicePath, 0);
    if (pDeviceInfo)
    {
        ddi_release_devi(pDeviceInfo);

        /*
         * Grab the root device node from the parent hub for resetting.
         */
        dev_info_t *pTmpDeviceInfo = NULL;
        for (;;)
        {
            pTmpDeviceInfo = ddi_get_parent(pDeviceInfo);
            if (!pTmpDeviceInfo)
            {
                LogRel((DEVICE_NAME ":vboxUSBMonSolarisResetDevice: Failed to get parent device info for %s\n", pszDevicePath));
                return VERR_GENERAL_FAILURE;
            }

            if (ddi_prop_exists(DDI_DEV_T_ANY, pTmpDeviceInfo, DDI_PROP_DONTPASS, "usb-port-count"))   /* parent hub */
                break;

            pDeviceInfo = pTmpDeviceInfo;
        }

        /*
         * Try re-enumerating the device.
         */
        rc = usb_reset_device(pDeviceInfo, fReattach ? USB_RESET_LVL_REATTACH : USB_RESET_LVL_DEFAULT);
        Log((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: usb_reset_device for %s level=%s rc=%d\n", pszDevicePath,
             fReattach ? "ReAttach" : "Default", rc));

        switch (rc)
        {
            case USB_SUCCESS:         rc = VINF_SUCCESS;                break;
            case USB_INVALID_PERM:    rc = VERR_PERMISSION_DENIED;      break;
            case USB_INVALID_ARGS:    rc = VERR_INVALID_PARAMETER;      break;
            case USB_BUSY:            rc = VERR_RESOURCE_BUSY;          break;
            case USB_INVALID_CONTEXT: rc = VERR_INVALID_CONTEXT;        break;
            case USB_FAILURE:         rc = VERR_GENERAL_FAILURE;        break;

            default:                  rc = VERR_UNRESOLVED_ERROR;       break;
        }
    }
    else
    {
        rc = VERR_INVALID_HANDLE;
        LogRel((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: Cannot obtain device info for %s\n", pszDevicePath));
    }

    return rc;
}
Ejemplo n.º 6
0
static void
ppb_removechild(dev_info_t *dip)
{
	struct ddi_parent_private_data *pdptr;
	ppb_devstate_t *ppb;

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(dip)));

	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
		pcie_fini_dom(dip);
		pcie_fini_cfghdl(dip);
	} else if ((pdptr = ddi_get_parent_data(dip)) != NULL) {
		kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec)));
		ddi_set_parent_data(dip, NULL);
	}
	ddi_set_name_addr(dip, NULL);

	/*
	 * Strip the node to properly convert it back to prototype form
	 */
	ddi_remove_minor_node(dip, NULL);

	impl_rem_dev_props(dip);
}
Ejemplo n.º 7
0
/*
 * nx1394_dma_allochdl()
 *    Merges the ddi_dma_attr_t passed in by the target (using
 *    ddi_dma_alloc_handle() call) with that of the hal and passes the alloc
 *    handle request up the device by calling ddi_dma_allochdl().
 */
static int
nx1394_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
    int (*waitfnp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
{
	s1394_hal_t *hal;
	ddi_dma_attr_t *hal_attr;
	int status;

	_NOTE(SCHEME_PROTECTS_DATA("unique (per thread)", ddi_dma_attr_t))

	TNF_PROBE_0_DEBUG(nx1394_dma_allochdl_enter, S1394_TNF_SL_NEXUS_STACK,
	    "");

	/*
	 * If hal calls ddi_dma_alloc_handle, dip == rdip == hal dip.
	 * Unfortunately, we cannot verify this (by way of looking up for hal
	 * dip) here because h1394_attach() may happen much later.
	 */
	if (dip != rdip) {
		hal = s1394_dip_to_hal(ddi_get_parent(rdip));
		ASSERT(hal);
		hal_attr = &hal->halinfo.dma_attr;
		ASSERT(hal_attr);
		ddi_dma_attr_merge(attr, hal_attr);
	}
	status = ddi_dma_allochdl(dip, rdip, attr, waitfnp, arg, handlep);
	TNF_PROBE_1_DEBUG(nx1394_dma_allochdl_exit, S1394_TNF_SL_NEXUS_STACK,
	    "", tnf_int, status, status);
	return (status);
}
Ejemplo n.º 8
0
/*
 * For a given instance, load that driver and its parents
 */
static int
load_parent_drivers(dev_info_t *dip, char *path)
{
	int	rval = 0;
	major_t	major = (major_t)-1;
	char	*drv;
	char	*p;

	while (dip) {
		/* check for path-oriented alias */
		if (path)
			major = ddi_name_to_major(path);
		else
			major = (major_t)-1;

		if (major != (major_t)-1)
			drv = ddi_major_to_name(major);
		else
			drv = ddi_binding_name(dip);

		if (load_boot_driver(drv) != 0)
			rval = -1;

		dip = ddi_get_parent(dip);
		if (path) {
			p = strrchr(path, '/');
			if (p)
				*p = 0;
		}
	}

	return (rval);
}
Ejemplo n.º 9
0
/*
 * Create a pci_pwr_chld_t structure for a given devinfo node.
 */
void
pci_pwr_create_info(pci_pwr_t *pwr_p, dev_info_t *dip)
{
	pci_pwr_chld_t *p;

	ASSERT(PM_CAPABLE(pwr_p));

	DEBUG2(DBG_PWR, ddi_get_parent(dip), "ADDING NEW PWR_INFO %s@%s\n",
	    ddi_node_name(dip), ddi_get_name_addr(dip));

	p = kmem_zalloc(sizeof (struct pci_pwr_chld), KM_SLEEP);
	p->dip = dip;

	mutex_enter(&pwr_p->pwr_mutex);

	/*
	 * Until components are created for this device, bus
	 * should be at full power since power of child device
	 * is unknown.  Increment # children requiring "full power"
	 */
	p->flags |= PWR_FP_HOLD;
	pwr_p->pwr_fp++;

	p->next =  pwr_p->pwr_info;
	pwr_p->pwr_info = p;

	pci_pwr_change(pwr_p, pwr_p->current_lvl, pci_pwr_new_lvl(pwr_p));

	mutex_exit(&pwr_p->pwr_mutex);
}
Ejemplo n.º 10
0
static int
sbbc_find_dip(dev_info_t *dip, void *arg)
{
	char		*node_name;
	sbbc_find_dip_t	*dip_struct = (sbbc_find_dip_t *)arg;
	char		status[OBP_MAXPROPNAME];

	/*
	 * Need to find a node named "bootbus-controller" that is neither
	 * disabled nor failed.  If a node is not ok, there will be an
	 * OBP status property.  Therefore, we will look for a node
	 * without the status property.
	 */
	node_name = ddi_node_name(dip);
	if (strcmp(node_name, "bootbus-controller") == 0 && DDI_CF2(dip) &&
		(prom_getprop(ddi_get_nodeid(dip),
		"status", (caddr_t)status) == -1) &&
		(prom_getprop(ddi_get_nodeid(ddi_get_parent(dip)),
		"status", (caddr_t)status) == -1)) {

		if (dip != dip_struct->cur_dip) {
			dip_struct->new_dip = (void *)dip;
			return (DDI_WALK_TERMINATE);
		}
	}

	return (DDI_WALK_CONTINUE);
}
Ejemplo n.º 11
0
/*
 * vdds_find_node -- A common function to find a NIU nexus or NIU node.
 */
static dev_info_t *
vdds_find_node(uint64_t cookie, dev_info_t *sdip,
	int (*match_func)(dev_info_t *dip, void *arg))
{
	vdds_cb_arg_t arg;
	dev_info_t *pdip;
	int circ;

	DBG1(NULL, "Called cookie=%lx\n", cookie);

	arg.dip = NULL;
	arg.cookie = cookie;

	if (pdip = ddi_get_parent(sdip)) {
		ndi_devi_enter(pdip, &circ);
	}

	ddi_walk_devs(sdip, match_func, (void *)&arg);
	if (pdip != NULL) {
		ndi_devi_exit(pdip, circ);
	}

	DBG1(NULL, "Returning dip=0x%p", arg.dip);
	return (arg.dip);
}
Ejemplo n.º 12
0
/*
 * Recursive ascent
 *
 * This now only does half the job.  It finds the node, then the caller
 * has to search the node for the binding name
 */
static in_node_t *
in_devwalk(dev_info_t *dip, in_node_t **ap, char *addr)
{
	in_node_t *np;
	char *name;

	ASSERT(dip);
	ASSERT(e_ddi_inst_state.ins_busy);
	if (dip == ddi_root_node()) {
		*ap = NULL;
		return (e_ddi_inst_state.ins_root);
	}
	/*
	 * call up to find parent, then look through the list of kids
	 * for a match
	 */
	np = in_devwalk(ddi_get_parent(dip), ap, NULL);
	if (np == NULL)
		return (np);
	*ap = np;
	np = np->in_child;
	name = ddi_node_name(dip);
	if (addr == NULL)
		addr = ddi_get_name_addr(dip);

	while (np) {
		if (in_eqstr(np->in_node_name, name) &&
		    in_eqstr(np->in_unit_addr, addr)) {
			return (np);
		}
		np = np->in_sibling;
	}
	return (np);
}
Ejemplo n.º 13
0
/*
 * 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);
}
Ejemplo n.º 14
0
int
get_portid_ddi(dev_info_t *dip, dev_info_t **cmpp)
{
    int portid;
    int i;
    char dev_type[OBP_MAXPROPNAME];
    int len = OBP_MAXPROPNAME;
    dev_info_t *cpu_parent;

    if (cmpp != NULL)
        *cmpp = NULL;

    if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                   DDI_PROP_DONTPASS, "portid", -1)) != -1)
        return (portid);
    if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                   DDI_PROP_DONTPASS, "upa-portid", -1)) != -1)
        return (portid);
    if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
                    DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type,
                    &len) != 0)
        return (-1);

    /*
     * For a virtual cpu node that is a CMP core, the "portid"
     * is in the parent node.
     * For a virtual cpu node that is a CMT strand, the "portid" is
     * in its grandparent node.
     * So we iterate up as far as 2 levels to get the "portid".
     */
    if (strcmp(dev_type, "cpu") == 0) {
        cpu_parent = dip = ddi_get_parent(dip);
        for (i = 0; dip != NULL && i < 2; i++) {
            if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                           DDI_PROP_DONTPASS, "portid", -1)) != -1) {
                if (cmpp != NULL)
                    *cmpp = cpu_parent;
                return (portid);
            }
            dip = ddi_get_parent(dip);
        }
    }

    return (-1);
}
Ejemplo n.º 15
0
/* Search the uwb handle with a hwarc/hwahc dip */
uwb_dev_handle_t
uwba_dev_search(dev_info_t *dip)
{
	mutex_enter(&uwba_mutex);
	uwba_dev_t *uwba_dev = list_head(&uwba_dev_list);

	while (uwba_dev != NULL) {
		if (ddi_get_parent(uwba_dev->dip)  == ddi_get_parent(dip)) {

			goto done;
		}
		uwba_dev = list_next(&uwba_dev_list, uwba_dev);
	}
done:
	mutex_exit(&uwba_mutex);

	return (uwb_dev_handle_t)(uwba_dev);
}
Ejemplo n.º 16
0
/* ARGSUSED */
void
i_ddi_remove_intrspec(dev_info_t *dip, dev_info_t *rdip,
    ddi_intrspec_t intrspec, ddi_iblock_cookie_t iblock_cookie)
{
	dev_info_t	*pdip = ddi_get_parent(dip);

	cmn_err(CE_WARN, "Failed to process interrupt "
	    "for %s%d due to down-rev nexus driver %s%d",
	    ddi_driver_name(rdip), ddi_get_instance(rdip),
	    ddi_driver_name(pdip), ddi_get_instance(pdip));
}
Ejemplo n.º 17
0
/*
 * Get the parent dip.
 */
static dev_info_t *
get_parent(dev_info_t *dip, struct parinfo *info)
{
	dev_info_t *pdip;

	pdip = ddi_get_parent(dip);
	ndi_hold_devi(pdip);
	info->dip = dip;
	info->pdip = pdip;
	return (pdip);
}
Ejemplo n.º 18
0
/* ARGSUSED */
ddi_intrspec_t
i_ddi_get_intrspec(dev_info_t *dip, dev_info_t *rdip, uint_t inumber)
{
	dev_info_t	*pdip = ddi_get_parent(dip);

	cmn_err(CE_WARN, "Failed to process interrupt "
	    "for %s%d due to down-rev nexus driver %s%d",
	    ddi_driver_name(rdip), ddi_get_instance(rdip),
	    ddi_driver_name(pdip), ddi_get_instance(pdip));

	return (NULL);
}
Ejemplo n.º 19
0
/* ARGSUSED */
int
i_ddi_intr_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_ctlop_t op,
    void *arg, void *val)
{
	dev_info_t	*pdip = ddi_get_parent(dip);

	cmn_err(CE_WARN, "Failed to process interrupt "
	    "for %s%d due to down-rev nexus driver %s%d",
	    ddi_driver_name(rdip), ddi_get_instance(rdip),
	    ddi_driver_name(pdip), ddi_get_instance(pdip));

	return (DDI_ENOTSUP);
}
Ejemplo n.º 20
0
int
pcmu_uninit_child(pcmu_t *pcmu_p, dev_info_t *child)
{
	PCMU_DBG2(PCMU_DBG_CTLOPS, pcmu_p->pcmu_dip,
	    "DDI_CTLOPS_UNINITCHILD: arg=%s%d\n",
	    ddi_driver_name(child), ddi_get_instance(child));

	ddi_set_name_addr(child, NULL);
	ddi_remove_minor_node(child, NULL);
	impl_rem_dev_props(child);

	PCMU_DBG0(PCMU_DBG_PWR, ddi_get_parent(child), "\n\n");
	return (DDI_SUCCESS);
}
Ejemplo n.º 21
0
static void
i_detach_ctlop(dev_info_t *devi, ddi_detach_cmd_t cmd, ddi_pre_post_t w,
    int ret)
{
	int error;
	struct detachspec ds;
	dev_info_t *pdip = ddi_get_parent(devi);

	ds.cmd = cmd;
	ds.when = w;
	ds.pdip = pdip;
	ds.result = ret;
	(void) ddi_ctlops(devi, devi, DDI_CTLOPS_DETACH, &ds, &error);
}
Ejemplo n.º 22
0
static void
i_attach_ctlop(dev_info_t *devi, ddi_attach_cmd_t cmd, ddi_pre_post_t w,
    int ret)
{
	int error;
	struct attachspec as;
	dev_info_t *pdip = ddi_get_parent(devi);

	as.cmd = cmd;
	as.when = w;
	as.pdip = pdip;
	as.result = ret;
	(void) ddi_ctlops(devi, devi, DDI_CTLOPS_ATTACH, &as, &error);
}
Ejemplo n.º 23
0
/* ARGSUSED */
int
i_ddi_add_intrspec(dev_info_t *dip, dev_info_t *rdip, ddi_intrspec_t intrspec,
    ddi_iblock_cookie_t *iblock_cookiep,
    ddi_idevice_cookie_t *idevice_cookiep,
    uint_t (*int_handler)(caddr_t int_handler_arg),
    caddr_t int_handler_arg, int kind)
{
	dev_info_t	*pdip = ddi_get_parent(dip);

	cmn_err(CE_WARN, "Failed to process interrupt "
	    "for %s%d due to down-rev nexus driver %s%d",
	    ddi_driver_name(rdip), ddi_get_instance(rdip),
	    ddi_driver_name(pdip), ddi_get_instance(pdip));

	return (DDI_ENOTSUP);
}
Ejemplo n.º 24
0
static struct ra_dip_type *
find_dip_map_resources(dev_info_t *dip, char *type,
    struct ra_dip_type ***backdip, struct ra_type_map ***backtype,
    uint32_t flag)
{
	struct ra_type_map **prevmap;
	struct ra_dip_type *dipmap, **prevdip;

	ASSERT(mutex_owned(&ra_lock));
	prevdip = NULL;
	dipmap = NULL;
	prevmap = &ra_map_list_head;

	while (*prevmap) {
		if (strcmp((*prevmap)->type, type) == 0)
			break;
		prevmap = &(*prevmap)->ra_next;
	}

	if (*prevmap) {
		for (; dip != NULL; dip = ddi_get_parent(dip)) {
			prevdip = &(*prevmap)->ra_dip_list;
			dipmap = *prevdip;

			while (dipmap) {
				if (dipmap->ra_dip == dip)
					break;
				prevdip =  &dipmap->ra_next;
				dipmap = dipmap->ra_next;
			}

			if (dipmap != NULL) {
				/* found it */
				break;
			}

			if (!(flag & NDI_RA_PASS)) {
				break;
			}
		}
	}

	*backtype = (*prevmap == NULL) ?  NULL: prevmap;
	*backdip = (dipmap == NULL) ?  NULL: prevdip;

	return (dipmap);
}
Ejemplo n.º 25
0
/*
 * cpunex_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.
 */
static int
cpunex_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
    void *result)
{
	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));
			return (DDI_SUCCESS);
		}

		case DDI_CTLOPS_INITCHILD: {
			dev_info_t *cdip = (dev_info_t *)arg;
			int i;
			char caddr[MAXNAMELEN];

			i = ddi_prop_get_int(DDI_DEV_T_ANY, cdip,
			    DDI_PROP_DONTPASS, "reg", -1);

			if (i == -1) {
				cmn_err(CE_NOTE, "!%s(%d): \"reg\" property "
				    "not found", ddi_node_name(cdip),
				    ddi_get_instance(cdip));
				return (DDI_NOT_WELL_FORMED);
			}

			(void) sprintf(caddr, "%d", i);
			ddi_set_name_addr(cdip, caddr);

			return (DDI_SUCCESS);
		}

		case DDI_CTLOPS_UNINITCHILD: {
			ddi_prop_remove_all((dev_info_t *)arg);
			ddi_set_name_addr((dev_info_t *)arg, NULL);
			return (DDI_SUCCESS);
		}

		default: {
			return (ddi_ctlops(dip, rdip, op, arg, result));
		}
	}
}
Ejemplo n.º 26
0
/*
 * Look first for an ACPI PCI bus node matching busid, then for a _PRT on the
 * parent node; then drop into the bridge-chasing code (which will also
 * look for _PRTs on the way up the tree of bridges)
 *
 * Stores polarity and sensitivity in the structure pointed to by
 * intr_flagp, and irqno in the value pointed to by pci_irqp.  *
 * Returns:
 *  	ACPI_PSM_SUCCESS on success.
 *	ACPI_PSM_PARTIAL to indicate need to configure the interrupt
 *	link device.
 * 	ACPI_PSM_FAILURE  if an error prevented the system from
 *	obtaining irq information for dip.
 */
int
acpi_translate_pci_irq(dev_info_t *dip, int ipin, int *pci_irqp,
    iflag_t *intr_flagp, acpi_psm_lnk_t *acpipsmlnkp)
{
	ACPI_HANDLE pciobj;
	int status = AE_ERROR;
	dev_info_t *curdip, *parentdip;
	int curpin, curbus, curdev;


	curpin = ipin;
	curdip = dip;
	while (curdip != ddi_root_node()) {
		parentdip = ddi_get_parent(curdip);
		ASSERT(parentdip != NULL);

		if (get_bdf(curdip, &curbus, &curdev, NULL) != 0)
			break;

		status = acpica_get_handle(parentdip, &pciobj);
		if ((status == AE_OK) && psm_node_has_prt(pciobj)) {
			return (acpi_get_gsiv(curdip, pciobj, curdev, curpin,
			    pci_irqp, intr_flagp, acpipsmlnkp));
		}

		/* if we got here, we need to traverse a bridge upwards */
		if (!psm_is_pci_bridge(parentdip))
			break;

		/*
		 * This is the rotating scheme that Compaq is using
		 * and documented in the PCI-PCI spec.  Also, if the
		 * PCI-PCI bridge is behind another PCI-PCI bridge,
		 * then it needs to keep ascending until an interrupt
		 * entry is found or the top is reached
		 */
		curpin = (curdev + curpin) % PCI_INTD;
		curdip = parentdip;
	}

	/*
	 * We should never, ever get here; didn't find a _PRT
	 */
	return (ACPI_PSM_FAILURE);
}
Ejemplo n.º 27
0
static void
ppb_uninitchild(dev_info_t *child)
{
	ppb_devstate_t *ppb;

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(child)));

	/*
	 * SG OPL FMA specific
	 */
	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
		pcie_fini_dom(child);
		pcie_fini_cfghdl(child);
	}

	ppb_removechild(child);
}
Ejemplo n.º 28
0
/*
 * Allocate space for component state information in pci_pwr_chld_t
 */
void
pci_pwr_add_components(pci_pwr_t *pwr_p, dev_info_t *cdip, pci_pwr_chld_t *p)
{
	int num_comps = PM_NUMCMPTS(cdip);
	int i;

	ASSERT(MUTEX_HELD(&pwr_p->pwr_mutex));
	/*
	 * Assume the power level of a component is UNKNOWN until
	 * notified otherwise.
	 */
	if (num_comps > 0) {
		p->comp_pwr =
		    kmem_alloc(sizeof (int) * num_comps, KM_SLEEP);
		p->num_comps = num_comps;

		DEBUG3(DBG_PWR, ddi_get_parent(cdip),
		    "ADDING %d COMPONENTS FOR %s@%s\n", num_comps,
		    ddi_node_name(cdip), ddi_get_name_addr(cdip));
	} else {
		cmn_err(CE_WARN, "%s%d device has %d components",
		    ddi_driver_name(cdip), ddi_get_instance(cdip),
		    num_comps);

		return;
	}

	/*
	 * Release the fp hold that was made when the device
	 * was created.
	 */
	ASSERT((p->flags & PWR_FP_HOLD) == PWR_FP_HOLD);
	p->flags &= ~PWR_FP_HOLD;
	pwr_p->pwr_fp--;

	for (i = 0; i < num_comps; i++) {
		/*
		 * Initialize the component lvl so that the
		 * state reference counts will be updated correctly.
		 */
		p->comp_pwr[i] = PM_LEVEL_NOLEVEL;
		pci_pwr_update_comp(pwr_p, p, i, PM_LEVEL_UNKNOWN);
	}
}
Ejemplo n.º 29
0
/*
 * nx1394_post_event()
 *    Called when a child node calls ddi_post_event. If the event is one of
 *    the events supported by us (bus reset/insert/remove, for now), builds
 *    a t1394_localinfo_t structure and calls ndi_event_run_callbacks(). This
 *    will result in all registered callbacks being invoked with
 *    t1394_localinfo_t as the impl_data. (see ddi_add_eventcall for callback
 *    arguments.) If the event is not defined by us, the request is
 *    propagated up the device tree by calling ndi_post_event().
 */
static int
nx1394_post_event(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t cookie,
    void *impl_data)
{
	int ret;
	char *name;
	s1394_hal_t *hal;
	t1394_localinfo_t localinfo;

	hal = s1394_dip_to_hal(dip);
	ASSERT(hal);

	TNF_PROBE_0_DEBUG(nx1394_post_event_enter, S1394_TNF_SL_NEXUS_STACK,
	    "");

	name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
	/* name is NULL if we don't generate the event */
	if (name != NULL) {

		mutex_enter(&hal->topology_tree_mutex);
		localinfo.bus_generation = hal->generation_count;
		localinfo.local_nodeID = hal->node_id;
		mutex_exit(&hal->topology_tree_mutex);
		impl_data = &localinfo;

		ret = ndi_event_run_callbacks(hal->hal_ndi_event_hdl,
		    rdip, cookie, impl_data);

		TNF_PROBE_4_DEBUG(nx1394_post_event_exit,
		    S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip,
		    (void *)dip, tnf_opaque, requestor_dip, (void *)rdip,
		    tnf_string, event_name, name, tnf_int, request_status, ret);
		return (ret);

	} else {
		ret = ndi_post_event(ddi_get_parent(dip), rdip, cookie,
		    impl_data);
		TNF_PROBE_2_DEBUG(nx1394_post_event_exit,
		    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, msg,
		    "Not our event", tnf_int, ret, ret);
		return (ret);
	}
}
Ejemplo n.º 30
0
/*ARGSUSED*/
static int
ppb_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
	off_t offset, off_t len, caddr_t *vaddrp)
{
	dev_info_t *pdip;
	ppb_devstate_t *ppb = ddi_get_soft_state(ppb_state,
	    ddi_get_instance(dip));

	if (strcmp(ddi_driver_name(ddi_get_parent(dip)), "npe") == 0 &&
	    mp->map_handlep != NULL) {
		ddi_acc_impl_t *hdlp =
		    (ddi_acc_impl_t *)(mp->map_handlep)->ah_platform_private;
		hdlp->ahi_err_mutexp = &ppb->ppb_err_mutex;
		hdlp->ahi_peekpoke_mutexp = &ppb->ppb_peek_poke_mutex;
		hdlp->ahi_scan_dip = dip;
		hdlp->ahi_scan = ppb_peekpoke_cb;
	}
	pdip = (dev_info_t *)DEVI(dip)->devi_parent;
	return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)(pdip,
	    rdip, mp, offset, len, vaddrp));
}