Пример #1
0
static int
gpio(di_minor_t minor, di_node_t node)
{
	char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath;
	char *minor_nm, *drvr_nm;


	minor_nm = di_minor_name(minor);
	drvr_nm = di_driver_name(node);
	if ((minor_nm == NULL) || (drvr_nm == NULL)) {
		return (DEVFSADM_CONTINUE);
	}

	devfspath = di_devfs_path(node);

	(void) strcpy(p_path, devfspath);
	(void) strcat(p_path, ":");
	(void) strcat(p_path, minor_nm);
	di_devfs_path_free(devfspath);

	/* build the physical path from the components */
	if (devfsadm_enumerate_int(p_path, 0, &buf, gpio_rules, 1)) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(l_path, sizeof (l_path), "%s%s", "gpio", buf);

	free(buf);

	(void) devfsadm_mklink(l_path, node, minor, 0);

	return (DEVFSADM_CONTINUE);
}
Пример #2
0
/*ARGSUSED*/
static scfga_ret_t
drv_to_dyncomp(di_node_t node, const char *phys, char **dyncompp, int *l_errnop)
{
	char *drv;
	int inst;
	const int dynlen = MAXPATHLEN;
	scfga_ret_t ret;

	*l_errnop = 0;

	if ((*dyncompp = calloc(1, dynlen)) == NULL) {
		*l_errnop = errno;
		return (SCFGA_LIB_ERR);
	}

	drv = di_driver_name(node);
	inst = di_instance(node);
	if (drv != NULL && inst != -1) {
		if (snprintf(*dyncompp, dynlen, "%s%d", drv, inst) < dynlen) {
			return (SCFGA_OK);
		} else {
			ret = SCFGA_LIB_ERR;
		}
	} else {
		ret = SCFGA_APID_NOEXIST;
	}

	S_FREE(*dyncompp);
	return (ret);
}
Пример #3
0
/*
 * Handles:
 *	minor node type "ddi_printer".
 * 	rules of the form: type=ddi_printer;name=bpp  \M0
 */
static int
printer_create(di_minor_t minor, di_node_t node)
{
	char *mn;
	char path[PATH_MAX + 1], *buf;
	devfsadm_enumerate_t rules[1] = {"^printers$/^([0-9]+)$", 1, MATCH_ALL};

	mn = di_minor_name(minor);

	if (strcmp(di_driver_name(node), "bpp") == 0) {
		(void) devfsadm_mklink(mn, node, minor, 0);
	}

	if (NULL == (buf = di_devfs_path(node))) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(path, sizeof (path), "%s:%s", buf, mn);
	di_devfs_path_free(buf);

	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(path, sizeof (path), "printers/%s", buf);
	free(buf);

	(void) devfsadm_mklink(path, node, minor, 0);

	return (DEVFSADM_CONTINUE);
}
Пример #4
0
/*
 * Called by di_walk_node() to walk the list of device nodes and
 * force all nodes of type "network" to be loaded.
 *
 * Returns: DI_WALK_CONTINUE
 */
static int
process_node(di_node_t node, void *arg)
{
	di_prom_handle_t ph = (di_prom_handle_t)arg;
	char *pdevtype;
	int ret;

	/*
	 * Only want to process nodes whose device_type is "network".
	 */
	ret = di_prom_prop_lookup_strings(ph, node, "device_type", &pdevtype);
	if ((ret <= 0) || (strcmp(pdevtype, "network") != 0)) {
		return (DI_WALK_CONTINUE);
	}

	/*
	 * If the instance is '-1', then the driver for the device
	 * has not been loaded - so force it to be loaded. Ignore
	 * errors loading the driver.
	 */
	if (di_instance(node) == -1) {
		node = di_init_driver(di_driver_name(node), 0);
		if (node != DI_NODE_NIL) {
			di_fini(node);
		}
	}
	return (DI_WALK_CONTINUE);
}
Пример #5
0
/*
 * This function is called for every dcam1394 minor node.
 * Calls enumerate to assign a logical dcam1394 id, and then
 * devfsadm_mklink to make the link.
 */
static int
dcam1394_process(di_minor_t minor, di_node_t node)
{
	char m_name[PATH_MAX], restring0[DCAM_RE_STRING_LEN];
	char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath;
	devfsadm_enumerate_t re[1];

	(void) strcpy(m_name, di_minor_name(minor));

	if (strcmp(di_driver_name(node), "dcam1394") != 0) {
	    return (DEVFSADM_CONTINUE);
	}

	if (strncmp(m_name, "dcamctl", 7) == 0) {
		(void) snprintf(restring0, DCAM_RE_STRING_LEN,
				DCAM_CTL_LINK_RE);
	} else if (strncmp(m_name, "dcam", 4) == 0) {
		(void) snprintf(restring0, DCAM_RE_STRING_LEN,
				DCAM_STR_LINK_RE);
	} else {
		return (DEVFSADM_CONTINUE);
	}

	re[0].re	= restring0;
	re[0].subexp	= 1;
	re[0].flags	= MATCH_ALL;

	devfsadm_print(debug_mid,
	    "dcam1394_process: path %s\n", di_devfs_path(node));

	(void) strcpy(p_path, devfspath = di_devfs_path(node));
	(void) strcat(p_path, ":");
	(void) strcat(p_path, di_minor_name(minor));
	di_devfs_path_free(devfspath);

	/*
	 * Build the physical path from the components, omitting
	 * minor name field.  Find the logical dcam1394 id, and
	 * stuff it in buf.
	 */
	if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) {
		devfsadm_print(debug_mid,
		    "dcam1394_process: exit/continue\n");
		return (DEVFSADM_CONTINUE);
	}

	devfsadm_print(debug_mid, "dcam1394_process: p_path=%s buf=%s\n",
	    p_path, buf);

	if (strncmp(di_minor_name(minor), "dcamctl", 7) == 0)
		(void) snprintf(l_path, PATH_MAX, "dcamctl%s", buf);
	else
		(void) snprintf(l_path, PATH_MAX, "dcam%s", buf);

	(void) devfsadm_mklink(l_path, node, minor, 0);

	free(buf);

	return (DEVFSADM_CONTINUE);
}
Пример #6
0
/*ARGSUSED*/
static int
MODULEprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	nvlist_t *mod;
	topo_mod_t *mp;
	char *dnm;
	int err;

	if ((dnm = di_driver_name(did_dinode(pd))) == NULL)
		return (0);

	mp = did_mod(pd);
	if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, dnm)) == NULL)
		return (0); /* driver maybe detached, return success */

	if (topo_prop_set_fmri(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, mod,
	    &err) < 0) {
		nvlist_free(mod);
		return (topo_mod_seterrno(mp, err));
	}
	nvlist_free(mod);

	return (0);
}
Пример #7
0
/* Make logical name for HBA  based on driver and instance */
static int
drv_to_hba_logid(di_node_t node, di_minor_t minor, void *arg)
{
	int inst;
	char *drv, *mn, *log;
	pathm_t *ptp;
	const size_t loglen = MAXPATHLEN;

	ptp = (pathm_t *)arg;

	errno = 0;

	mn = di_minor_name(minor);
	drv = di_driver_name(node);
	inst = di_instance(node);
	log = calloc(1, loglen);

	if (mn != NULL && drv != NULL && inst != -1 && log != NULL) {
		/* Count does not include terminating NULL */
		if (snprintf(log, loglen, "%s%d:%s", drv, inst, mn) < loglen) {
			ptp->ret = SCFGA_OK;
			ptp->log = log;
			return (DI_WALK_TERMINATE);
		}
	}

	S_FREE(log);
	return (DI_WALK_CONTINUE);
}
Пример #8
0
/*
 * Handles links of the form:
 * type=ddi_printer;name=ecpp  ecpp\N0
 */
static int
ecpp_create(di_minor_t minor, di_node_t node)
{
	char *buf;
	char path[PATH_MAX + 1];
	devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};

	if (strcmp(di_driver_name(node), "ecpp") != 0) {
		return (DEVFSADM_CONTINUE);
	}

	if ((buf = di_devfs_path(node)) == NULL) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(path, sizeof (path), "%s:%s",
	    buf, di_minor_name(minor));

	di_devfs_path_free(buf);

	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(path, sizeof (path), "ecpp%s", buf);
	free(buf);

	(void) devfsadm_mklink(path, node, minor, 0);
	return (DEVFSADM_CONTINUE);
}
Пример #9
0
/*
 * handle case where device has been probed but its target driver is not
 * attached so enumeration has not quite finished. Opening the /devices
 * pathname will force the kernel to finish the enumeration process and
 * let us get the data we need.
 */
static void
get_devid(di_node_t node, ddi_devid_t *thisdevid)
{
	int fd;
	char realpath[MAXPATHLEN];
	char *openpath = di_devfs_path(node);

	errno = 0;
	bzero(realpath, MAXPATHLEN);
	if (strstr(openpath, "/devices") == NULL) {
		(void) snprintf(realpath, MAXPATHLEN,
		    "/devices%s:c,raw", openpath);
		fd = open(realpath, O_RDONLY|O_NDELAY);
	} else {
		fd = open(openpath, O_RDONLY|O_NDELAY);
	}

	if (fd < 0) {
		logmsg(MSG_INFO, "Unable to open path %s: %s\n",
		    openpath, strerror(errno));
		return;
	}

	if (devid_get(fd, thisdevid) != 0) {
		logmsg(MSG_INFO,
		    "'%s' node (%s) without a devid registered\n",
		    di_driver_name(node), di_devfs_path(node));
	}
	(void) close(fd);
}
Пример #10
0
/*
 * Called by di_walk_minor() to walk the list
 * of ddi_network minor device nodes and add
 * the interface to the niclist.
 *
 * Returns: DI_WALK_CONTINUE or DI_WALK_TERMINATE.
 */
static int
nic_process_minor_nodes(di_node_t node, di_minor_t minor, void *arg)
{
	wlkreq_t *request = (wlkreq_t *)arg;
	niclist_t **niclist = request->wr_niclist;
	char *name;
	char *nodetype;
	int instance;
	int ret;

	/*
	 * Look for network devices only. Unfortunately, our walk will
	 * include nodes with nodetypes of NULL.
	 */
	nodetype = di_minor_nodetype(minor);
	if ((nodetype == NULL) || (strcmp(nodetype, DDI_NT_NET) != 0)) {
		return (DI_WALK_CONTINUE);
	}

	/*
	 * In the case of DDM_MINOR minor nodes, the minor
	 * name is the name of the driver. However, if the name
	 * doesn't include the instance, then it's not one
	 * one we're interested in. In the case of other
	 * minor nodes, we should be able to get the driver name
	 * and its instance from the node properties. If they are
	 * not valid, then we're not interested in them.
	 */
	if (di_minor_type(minor) == DDM_MINOR) {
		name = di_minor_name(minor);
		if ((name == NULL) || (strlen(name) == 0) ||
		    (!isdigit(name[strlen(name) - 1]))) {
			return (DI_WALK_CONTINUE);
		}
		instance = -1;
	} else {
		name = di_driver_name(node);
		instance = di_instance(node);
		if ((name == NULL) || (strlen(name) == 0) ||
		    (instance == -1)) {
			return (DI_WALK_CONTINUE);
		}
	}

	/*
	 * Add this one to the niclist.
	 */
	ret = nic_add(niclist, name, instance, request->wr_syserr);
	if (ret != ICFG_SUCCESS) {
		(*request->wr_err) = ret;
		return (DI_WALK_TERMINATE);
	}
	(*request->wr_numif)++;

	return (DI_WALK_CONTINUE);

}
Пример #11
0
static int vboxSolarisAddPhysHostIface(di_node_t Node, di_minor_t Minor, void *pvHostNetworkInterfaceList)
{
    NOREF(Minor);

    /*
     * Skip aggregations.
     */
    if (!strcmp(di_driver_name(Node), "aggr"))
        return DI_WALK_CONTINUE;

    /*
     * Skip softmacs.
     */
    if (!strcmp(di_driver_name(Node), "softmac"))
        return DI_WALK_CONTINUE;

    vboxSolarisAddHostIface(di_driver_name(Node), di_instance(Node), pvHostNetworkInterfaceList);
    return DI_WALK_CONTINUE;
}
Пример #12
0
static int
driver_minor(di_minor_t minor, di_node_t node)
{
	char path[PATH_MAX + 1];

	(void) strcpy(path, di_driver_name(node));
	(void) strcat(path, di_minor_name(minor));
	(void) devfsadm_mklink(path, node, minor, 0);
	return (DEVFSADM_CONTINUE);
}
static USBDEVICESTATE solarisDetermineUSBDeviceState(PUSBDEVICE pDevice, di_node_t Node)
{
    char *pszDriverName = di_driver_name(Node);

    /* Not possible unless a user explicitly unbinds the default driver. */
    if (!pszDriverName)
        return USBDEVICESTATE_UNUSED;

    if (!strncmp(pszDriverName, VBOXUSB_DRIVER_NAME, sizeof(VBOXUSB_DRIVER_NAME) - 1))
        return USBDEVICESTATE_HELD_BY_PROXY;

    NOREF(pDevice);
    return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
}
Пример #14
0
/*ARGSUSED*/
static int
driverprop_set(tnode_t *tn, di_node_t dn,
	const char *tpgrp, const char *tpnm, topo_mod_t *mod)
{
	char *dnm;
	int err;

	if ((dnm = di_driver_name(dn)) == NULL)
		return (0);
	if (topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, dnm, &err) < 0)
		return (topo_mod_seterrno(mod, err));
	return (0);
}
Пример #15
0
/*ARGSUSED*/
static int
DRIVERprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	char *dnm;
	int err;

	if ((dnm = di_driver_name(did_dinode(pd))) == NULL)
		return (0);
	if (topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, dnm, &err) < 0)
		return (topo_mod_seterrno(did_mod(pd), err));

	return (0);
}
Пример #16
0
static int
getnameinst(char *path, int *instance, char *name, int namelen)
{
	di_node_t node;
	char *driver_name;

	if ((node = di_init(&path[8], DINFOSUBTREE)) == DI_NODE_NIL)
		return (-1);
	if ((driver_name = di_driver_name(node)) == NULL) {
		di_fini(node);
		return (-1);
	}
	*instance = di_instance(node);
	(void) strncpy(name, driver_name, namelen);
	di_fini(node);
	return (0);
}
Пример #17
0
void
devinfo_set_default_properties (HalDevice *d, HalDevice *parent, di_node_t node, char *devfs_path)
{
	char	*driver_name, *s;
	const char *s1;
	char	udi[HAL_PATH_MAX];

	if (parent != NULL) {
		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
	} else {
		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/local");
	}

	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
				"/org/freedesktop/Hal/devices%s_%d",
				devfs_path,
				di_instance (node));
	hal_device_set_udi (d, udi);
	hal_device_property_set_string (d, "info.udi", udi);

	if (di_prop_lookup_strings (DDI_DEV_T_ANY, node, "model", &s) > 0) {
		hal_device_property_set_string (d, "info.product", s);
	} else {
		hal_device_property_set_string (d, "info.product", di_node_name (node));
	}

	hal_device_property_set_string (d, "solaris.devfs_path", devfs_path);

	if ((driver_name = di_driver_name (node)) != NULL) {
		hal_device_property_set_string (d, "info.solaris.driver",
						driver_name);
	}


	/* inherit parent's claim attributes */
	if (hal_device_property_get_bool (parent, "info.claimed")) {
		s1 = hal_device_property_get_string (parent, "info.claimed.service");
		if (s1 != NULL) {
			hal_device_property_set_bool (d, "info.claimed", TRUE);
			hal_device_property_set_string (d, "info.claimed.service", s1);
		}
	}
}
Пример #18
0
/*ARGSUSED*/
static int
load_driver(di_node_t node, void *arg)
{
	char *drv_name = NULL;
	char cmd[MAXPATHLEN];

	if (di_node_state(node) >= DS_ATTACHED) {
		return (DI_WALK_CONTINUE);
	}
	drv_name = di_driver_name(node);
	if (drv_name == NULL) {
		return (DI_WALK_CONTINUE);
	}

	(void) snprintf(cmd, sizeof (cmd), "%s %s",
		DEVFSADM_CMD, drv_name);
	(void) pclose(popen(cmd, "r"));
	return (DI_WALK_CONTINUE);
}
Пример #19
0
static void
get_phci_driver_name(char *phci_path, char **driver_name)
{
	di_node_t phci_node = DI_NODE_NIL;
	char *tmp = NULL;

	phci_node = di_init(phci_path, DINFOCPYONE);
	if (phci_node == DI_NODE_NIL) {
		logmsg(MSG_ERROR,
		    gettext("Unable to take phci snapshot "
		    "(%s: %d)\n"), strerror(errno), errno);
		return;
	}
	tmp = di_driver_name(phci_node);
	if (tmp != NULL) {
		(void) strncpy(*driver_name, tmp, 10);
	}
	di_fini(phci_node);
}
Пример #20
0
static int
walk_callback(di_node_t node, void *arg)
{
	struct walk_arg *warg = (struct walk_arg *)arg;
	char *driver_name;
	char *path;

	driver_name = di_driver_name(node);
	if (driver_name != NULL) {
		if (strcmp(driver_name, warg->name) == 0 &&
		    di_instance(node) == warg->instance) {
			path = di_devfs_path(node);
			if (path != NULL) {
				warg->found = 1;
				(void) strncpy(warg->path, path, warg->pathlen);
			}
			return (DI_WALK_TERMINATE);
		}
	}
	return (DI_WALK_CONTINUE);
}
Пример #21
0
static struct priv_data *
match_priv_data(di_node_t node)
{
	int i;
	size_t len;
	char *drv_name, *tmp;
	di_node_t parent;
	struct priv_data *pdp;

	if ((parent = di_parent_node(node)) == DI_NODE_NIL)
		return (NULL);

	if ((drv_name = di_driver_name(parent)) == NULL)
		return (NULL);

	pdp = prt_priv_data;
	len = strlen(drv_name);
	for (i = 0; i < nprt_priv_data; ++i, ++pdp) {
		tmp = pdp->drv_name;
		while (tmp && (*tmp != '\0')) {
			if (strncmp(tmp, drv_name, len) == 0) {
#ifdef	DEBUG
				dprintf("matched parent private data"
				    " at Node <%s> parent driver <%s>\n",
				    di_node_name(node), drv_name);
#endif	/* DEBUG */
				return (pdp);
			}
			/*
			 * skip a white space
			 */
			if (tmp = strchr(tmp, ' '))
				tmp++;
		}
	}

	return (NULL);
}
Пример #22
0
/*ARGSUSED*/
static int
moduleprop_set(tnode_t *tn, di_node_t dn,
	const char *tpgrp, const char *tpnm, topo_mod_t *mod)
{
	nvlist_t *module;
	char *dnm;
	int err;

	if ((dnm = di_driver_name(dn)) == NULL)
		return (0);

	if ((module = topo_mod_modfmri(mod, FM_MOD_SCHEME_VERSION, dnm))
	    == NULL)
		return (0); /* driver maybe detached, return success */

	if (topo_prop_set_fmri(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, module,
	    &err) < 0) {
		nvlist_free(module);
		return (topo_mod_seterrno(mod, err));
	}
	nvlist_free(module);
	return (0);
}
static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList)
{
	int numNodes = 0;
	int instNum = 0;
	int majorNum = 0;

	di_node_t vh_node	= DI_NODE_NIL;
	di_node_t ph_node	= DI_NODE_NIL;

	MP_UINT64 osn = 0;

	int haveList = (NULL != pOidList);


	log(LOG_INFO, "getOidList()", " - enter");

	vh_node = di_vhci_first_node(root_node);

	while (DI_NODE_NIL != vh_node) {
		if ((di_driver_name(vh_node) != NULL) &&
		    (strncmp(di_driver_name(vh_node), "scsi_vhci", 9) == 0)) {
			ph_node = di_phci_first_node(vh_node);
			while (DI_NODE_NIL != ph_node) {
				if (haveList) {

					instNum  = di_instance(ph_node);
					majorNum = di_driver_major(ph_node);

					log(LOG_INFO, "getOidList()",
						"instNum = %d",
						instNum);

					log(LOG_INFO, "getOidList()",
						"majorNum = %d",
						majorNum);

					if (numNodes < pOidList->oidCount) {

						osn = 0;

						osn =
						MP_STORE_INST_TO_ID(instNum,
								osn);

						osn =
						MP_STORE_MAJOR_TO_ID(majorNum,
								osn);

						pOidList->oids[numNodes]
							.objectSequenceNumber =
							osn;

						pOidList->oids[numNodes].
							objectType =
						MP_OBJECT_TYPE_INITIATOR_PORT;

						pOidList->oids[numNodes].
							ownerId =
							g_pluginOwnerID;
					}
				}

				++numNodes;
				ph_node = di_phci_next_node(ph_node);
			}

		}
		vh_node = di_vhci_next_node(vh_node);
	}

	log(LOG_INFO,
		"getOidList()",
		" - numNodes: %d",
		numNodes);


	log(LOG_INFO, "getOidList()", " - exit");

	return (numNodes);
}
Пример #24
0
/*
 * Determine whether the interface was configured manually.
 */
static boolean_t
manual_if_init(void)
{
	boolean_t	ret = B_FALSE;
	char		*ncs;
	char		*devpath;
	di_node_t	node;
	int		instance;
	char		*drvname;
	char		ifname[IFNAMSIZ + 1];

	/*
	 * If net-config-strategy isn't "manual", don't go any further.
	 */
	if ((ncs = get_prop("chosen", BI_NET_CONFIG_STRATEGY, NULL)) == NULL ||
	    strcmp(ncs, "manual") != 0) {
		return (B_FALSE);
	}

	/*
	 * First check the 'bootpath' property of /chosen to see whether
	 * it specifies the path of a network device; if so, use this.
	 */
	if ((devpath = get_bootpath()) == NULL ||
	    (node = path2node(devpath)) == DI_NODE_NIL ||
	    !is_network_device(node)) {
		/*
		 * Must have been booted from CD-ROM or disk; attempt to
		 * use the path defined by the 'net' property of /aliases.
		 */
		free(devpath);
		if ((devpath = get_netalias()) == NULL ||
		    (node = path2node(devpath)) == DI_NODE_NIL ||
		    !is_network_device(node)) {
			goto cleanup;
		}
	}

	/*
	 * Get the driver name and instance number of this node.
	 * We may have to load the driver.
	 */
	if ((drvname = di_driver_name(node)) == NULL) {
		goto cleanup;
	}
	if ((instance = di_instance(node)) == -1) {
		di_node_t	tmp;

		/*
		 * Attempt to load the driver, create a new snapshot of the
		 * (possibly changed) device tree and re-compute our node.
		 */
		if ((tmp = di_init_driver(drvname, 0)) != DI_NODE_NIL) {
			di_fini(tmp);

			if (!snapshot_devtree() ||
			    (node = path2node(devpath)) == DI_NODE_NIL) {
				goto cleanup;
			}
		}
		instance = di_instance(node);
	}

	/*
	 * Construct the interface name.
	 */
	if (instance == -1) {
		(void) snprintf(ifname, sizeof (ifname),
		    "%s", di_driver_name(node));
	} else {
		(void) snprintf(ifname, sizeof (ifname),
		    "%s%d", di_driver_name(node), instance);
	}

	ret = netif_init(ifname, "manual");
cleanup:
	free(devpath);
	return (ret);
}
Пример #25
0
/*
 * Operates on a single di_node_t, collecting all the device properties
 * that we need. devnvl is allocated by the caller, and we add our nvpairs
 * to it if they don't already exist.
 *
 * We are _only_ interested in devices which have a devid. We pull in
 * devices even when they're excluded via stmsboot -D (driver), because
 * we don't want to miss out on any devid data that might be handy later.
 */
static int
popcheck_devnvl(di_node_t thisnode, nvlist_t *devnvl, char *strdevid)
{
	char *path = NULL;
	char *curpath = NULL;
	char *devfspath = NULL;
	char *prop = NULL;
	int scsivhciparent = 0;
	int rv = 0;
	boolean_t mpxenp = B_FALSE;

	errno = 0;
	devfspath = di_devfs_path(thisnode);
	if (devfspath == NULL) {
		logmsg(MSG_ERROR,
		    gettext("Unable to determine devfs path for node: %s\n"),
		    strerror(errno));
		return (-1);
	}

	/* Add a convenient devfspath to devid inverse map */
	if (nvlist_add_string(mapnvl, devfspath, strdevid) != 0) {
		logmsg(MSG_ERROR,
		    gettext("Unable to add device path %s with devid "
		    "%s to mapnvl\n"), devfspath, strdevid);
		return (-1);
	}
	if (di_prop_lookup_strings(DDI_DEV_T_ANY, di_parent_node(thisnode),
	    "mpxio-disable", &prop) >= 0) {
		if (strncmp(prop, "yes", 3) == 0) {
			if (!mpxprop)
				mpxprop++;
		}
	}

	if (strncmp(di_driver_name(di_parent_node(thisnode)),
	    "scsi_vhci", 9) == 0) {
		scsivhciparent = 1;
		if (!mpxenabled)
			mpxenabled++;

		rv = nvlist_lookup_boolean_value(devnvl, NVL_MPXEN, &mpxenp);
		if (rv || (mpxenp == B_FALSE)) {
			rv = nvlist_add_boolean_value(devnvl,
			    NVL_MPXEN, B_TRUE);
			if (rv) {
				logmsg(MSG_ERROR,
				    gettext("Unable to add property %s "
				    "(set to B_TRUE) for device %s: "
				    "%s (%d)\n"),
				    NVL_MPXEN, devfspath,
				    strerror(rv), rv);
				return (-1);
			}
			logmsg(MSG_INFO, "NVL_MPXEN :: (B_FALSE->B_TRUE)\n");
		}
	} else {
		/* turn _off_ the flag if it was enabled */
		rv = nvlist_add_boolean_value(devnvl, NVL_MPXEN, B_FALSE);
		if (rv) {
			logmsg(MSG_ERROR,
			    gettext("Unable to add property %s "
			    "(set to B_FALSE) for device %s: %s (%d)\n"),
			    NVL_MPXEN, devfspath,
			    strerror(rv), rv);
			return (-1);
		}
		logmsg(MSG_INFO, "NVL_MPXEN :: (B_TRUE-> B_FALSE)\n");
	}

	rv = nvlist_add_string(devnvl, NVL_PHYSPATH, devfspath);
	if (rv) {
		logmsg(MSG_ERROR,
		    gettext("Unable to add physical device path (%s) "
		    "property to nvl\n"));
		return (-1);
	}

	if ((curpath = calloc(1, MAXPATHLEN)) == NULL) {
		logmsg(MSG_ERROR,
		    gettext("Unable to allocate space for current path\n"));
		return (-1);
	}
	curpath = find_link(thisnode);
	if (curpath == NULL) {
		if (readonlyroot) {
			return (0);
		}
		logmsg(MSG_ERROR,
		    gettext("Unable to determine device path for node %s\n"),
		    devfspath);
		return (-1);
	}

	rv = nvlist_lookup_string(devnvl, NVL_MPXPATH, &path);

	if (scsivhciparent) {
		(void) nvlist_add_string(devnvl, NVL_MPXPATH, curpath);
	} else {
		(void) nvlist_add_string(devnvl, NVL_PATH, curpath);
		path = curpath;
	}

	/*
	 * This next block provides the path to devid inverse mapping
	 * that other functions require
	 */
	if (path != NULL) {
		if (nvlist_add_string(mapnvl, path, strdevid) != 0) {
			logmsg(MSG_ERROR,
			    gettext("Unable to add device %s with devid "
			    "%s to mapnvl\n"), path, strdevid);
			return (-1);
		}
		logmsg(MSG_INFO, "popcheck_devnvl: added path %s :: %s\n",
		    path, strdevid);
	}

	if (nvlist_add_string(mapnvl, curpath, strdevid) != 0) {
			logmsg(MSG_ERROR,
			    gettext("Unable to add device %s with devid "
			    "%s to mapnvl: %s\n"),
			    curpath, strdevid, strerror(errno));
			return (-1);
	}
	logmsg(MSG_INFO, "popcheck_devnvl: added curpath %s :: %s\n",
	    curpath, strdevid);

	return (0);
}
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
{
    PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg;
    AssertPtrReturn(pList, DI_WALK_TERMINATE);

    /*
     * Check if it's a USB device in the first place.
     */
    bool fUSBDevice = false;
    char *pszCompatNames = NULL;
    int cCompatNames = di_compatible_names(Node, &pszCompatNames);
    for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1)
        if (!strncmp(pszCompatNames, "usb", 3))
        {
            fUSBDevice = true;
            break;
        }

    if (!fUSBDevice)
        return DI_WALK_CONTINUE;

    /*
     * Check if it's a device node or interface.
     */
    int *pInt = NULL;
    char *pStr = NULL;
    int rc = DI_WALK_CONTINUE;
    if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0)
    {
        /* It's a device node. */
        char *pszDevicePath = di_devfs_path(Node);
        PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur));
        if (!pCur)
        {
            LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur)));
            return DI_WALK_TERMINATE;
        }

        bool fValidDevice = false;
        do
        {
            AssertBreak(pszDevicePath);

            char *pszDriverName = di_driver_name(Node);

            /*
             * Skip hubs
             */
            if (   pszDriverName
                && !strcmp(pszDriverName, "hubd"))
            {
                break;
            }

            /*
             * Mandatory.
             * snv_85 and above have usb-dev-descriptor node properties, but older one's do not.
             * So if we cannot obtain the entire device descriptor, we try falling back to the
             * individual properties (those must not fail, if it does we drop the device).
             */
            uchar_t *pDevData = NULL;
            int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData);
            if (   cbProp > 0
                && pDevData)
            {
                usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData;
                pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass;
                pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass;
                pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol;
                pCur->idVendor = pDeviceDescriptor->idVendor;
                pCur->idProduct = pDeviceDescriptor->idProduct;
                pCur->bcdDevice = pDeviceDescriptor->bcdDevice;
                pCur->bcdUSB = pDeviceDescriptor->bcdUSB;
                pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations;
                pCur->fPartialDescriptor = false;
            }
            else
            {
                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0);
                pCur->idVendor = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0);
                pCur->idProduct = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0);
                pCur->bcdDevice = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0);
                pCur->bcdUSB = (uint16_t)*pInt;

                pCur->fPartialDescriptor = true;
            }

            char *pszPortAddr = di_bus_addr(Node);
            if (pszPortAddr)
                pCur->bPort = RTStrToUInt8(pszPortAddr);     /* Bus & Port are mixed up (kernel driver/userland) */
            else
                pCur->bPort = 0;

            char pathBuf[PATH_MAX];
            RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath);
            RTPathStripFilename(pathBuf);

            char szBuf[PATH_MAX + 48];
            RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pathBuf);
            pCur->pszAddress = RTStrDup(szBuf);

            pCur->pszDevicePath = RTStrDup(pszDevicePath);
            AssertBreak(pCur->pszDevicePath);

            /*
             * Optional (some devices don't have all these)
             */
            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0)
                pCur->pszProduct = RTStrDup(pStr);

            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0)
                pCur->pszManufacturer = RTStrDup(pStr);

            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0)
                pCur->pszSerialNumber = RTStrDup(pStr);

            if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0)
                pCur->enmSpeed = USBDEVICESPEED_LOW;
            else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0)
                pCur->enmSpeed = USBDEVICESPEED_HIGH;
            else
                pCur->enmSpeed = USBDEVICESPEED_FULL;

            /* Determine state of the USB device. */
            pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);

            /*
             * Valid device, add it to the list.
             */
            fValidDevice = true;
            pCur->pPrev = pList->pTail;
            if (pList->pTail)
                pList->pTail = pList->pTail->pNext = pCur;
            else
                pList->pTail = pList->pHead = pCur;

            rc = DI_WALK_CONTINUE;
        } while(0);

        di_devfs_path_free(pszDevicePath);
        if (!fValidDevice)
            solarisFreeUSBDevice(pCur);
    }
    return rc;
}
Пример #27
0
/*
 * Retrieves the statistics for a specified port.phy on an adapter
 */
HBA_STATUS Sun_sasGetPhyStatistics(HBA_HANDLE handle,
    HBA_UINT32 port, HBA_UINT32 phy, SMHBA_PHYSTATISTICS *pStatistics) {
	const char	ROUTINE[] = "Sun_sasGetPhyStatistics";
	HBA_STATUS		status = HBA_STATUS_OK;
	struct sun_sas_hba	*hba_ptr;
	struct sun_sas_port	*hba_port_ptr;
	struct phy_info		*phy_ptr;
	PSMHBA_SASPHYSTATISTICS	psas;
	kstat_ctl_t		*kc;
	kstat_t			*ksp;
	kstat_named_t		*kname;
	char			*charptr, path[MAXPATHLEN + 1];
	char			*driver_name, kstat_name[256];
	di_node_t		node;
	int			instance = 0;
	int			i;
	uint64_t		iport_wwn;

	/* Validate the arguments */
	if (pStatistics == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "NULL Phy Statistics buffer of phyIndex: %08lx", phy);
		return (HBA_STATUS_ERROR_ARG);
	}
	psas = pStatistics->SASPhyStatistics;
	if (psas == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "NULL SAS Phy Statistics buffer of phyIndex: %08lx", phy);
		return (HBA_STATUS_ERROR_ARG);
	}

	lock(&all_hbas_lock);

	if ((hba_ptr = Retrieve_Sun_sasHandle(handle)) == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "Invalid HBA handler %08lx of phyIndex: %08lx",
		    handle, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_INVALID_HANDLE);
	}

	/* Check for stale data */
	status = verifyAdapter(hba_ptr);
	if (status != HBA_STATUS_OK) {
		log(LOG_DEBUG, ROUTINE,
		    "Verify Adapter failed for phyIndex: %08lx", phy);
		unlock(&all_hbas_lock);
		return (status);
	}

	for (hba_port_ptr = hba_ptr->first_port;
	    hba_port_ptr != NULL;
	    hba_port_ptr = hba_port_ptr->next) {
		if (hba_port_ptr->index == port) {
			break;
		}
	}

	if (hba_port_ptr == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "Invalid port index of phyIndex: %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	if (phy >= hba_port_ptr->port_attributes.PortSpecificAttribute.
	    SASPort->NumberofPhys) {
		log(LOG_DEBUG, ROUTINE, "Invalid phy index %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	/* We need to find out the phy identifier. */
	for (phy_ptr = hba_port_ptr->first_phy;
	    phy_ptr != NULL;
	    phy_ptr = phy_ptr->next) {
		if (phy == phy_ptr->index)
			break;
	}

	if (phy_ptr == NULL) {
		log(LOG_DEBUG, ROUTINE, "Invalid phy index %08lx", phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR_ILLEGAL_INDEX);
	}

	/*
	 * for statistics that are not supported, its bits should all be
	 * set to -1
	 */
	(void) memset(pStatistics->SASPhyStatistics, 0xff,
	    sizeof (SMHBA_SASPHYSTATISTICS));


	/* First, we need the deivce path to locate the devinfo node. */
	(void *) strlcpy(path, hba_port_ptr->device_path,
	    sizeof (path));
	charptr = strrchr(path, ':');
	if (charptr) {
		*charptr = '\0';
	}

	errno = 0;

	(void *) memset(kstat_name, 0, sizeof (kstat_name));
	node = di_init(path, DINFOCPYONE);
	if (node == DI_NODE_NIL) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "Unable to take devinfo snapshot on HBA \"%s\" "
		    "for phyIndex: %08lx due to %s",
		    path, phy, strerror(errno));
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	/*
	 * Then we could fetch the instance number and driver name of this
	 * device.
	 */
	instance = di_instance(node);
	if (instance == -1) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "An instance number has not been assigned to the "
		    "device \"%s\" when get phyIndex: %08lx", path, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	driver_name = di_driver_name(node);
	if (driver_name == NULL) {
		di_fini(node);
		log(LOG_DEBUG, ROUTINE,
		    "No driver bound to this device \"%s\" "
		    "when get phyIndex: %08lx",
		    path, phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}

	di_fini(node);

	iport_wwn = wwnConversion(hba_port_ptr->port_attributes.\
	    PortSpecificAttribute.SASPort->LocalSASAddress.wwn);

	/*
	 * Construct the kstat name here.
	 */
	(void) snprintf(kstat_name, sizeof (kstat_name), "%s.%016llx.%u.%u",
	    driver_name, iport_wwn, instance, phy_ptr->phy.PhyIdentifier);

	/* retrieve all the statistics from kstat. */
	kc = kstat_open();
	if (kc == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "kstat_open failed due to \"%s\" of phyIndex: %08lx",
		    strerror(errno), phy);
		unlock(&all_hbas_lock);
		return (HBA_STATUS_ERROR);
	}
	ksp = kstat_lookup(kc, NULL, -1, kstat_name);
	if (ksp == NULL) {
		log(LOG_DEBUG, ROUTINE,
		    "No matching kstat name found for \"%s\" "
		    "of phyIndex: %08lx",
		    kstat_name, phy);
		unlock(&all_hbas_lock);
		(void) kstat_close(kc);
		return (HBA_STATUS_ERROR);
	}
	/* Found the phy we're looking for. */
	if (kstat_read(kc, ksp, NULL) == -1) {
		log(LOG_DEBUG, ROUTINE,
		    "error reading kstat data due to \"%s\" "
		    "of phyIndex: %08lx",
		    strerror(errno), phy);
		unlock(&all_hbas_lock);
		(void) kstat_close(kc);
		return (HBA_STATUS_ERROR);
	}

	kname = (kstat_named_t *)ksp->ks_data;
	for (i = 0; i < ksp->ks_ndata; i++, kname++) {
		if (strcmp(kname->name,
		    "SecondsSinceLastReset") == 0) {
		    psas->SecondsSinceLastReset = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "TxFrames") == 0) {
			psas->TxFrames = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RxFrames") == 0) {
			psas->RxFrames = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "TxWords") == 0) {
			psas->TxWords = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RxWords") == 0) {
			psas->RxWords = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "InvalidDwordCount") == 0) {
			psas->InvalidDwordCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "RunningDisparityErrorCount") == 0) {
			psas->RunningDisparityErrorCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "LossofDwordSyncCount") == 0) {
			psas->LossofDwordSyncCount = kname->value.ull;
			continue;
		}
		if (strcmp(kname->name, "PhyResetProblemCount") == 0) {
			psas->PhyResetProblemCount = kname->value.ull;
		}
	}
	unlock(&all_hbas_lock);
	(void) kstat_close(kc);

	return (HBA_STATUS_OK);
}
Пример #28
0
/* Converts a driver and instance number based logid into a physical path */
static int
do_drv_dyn_to_devpath(di_node_t node, void *arg)
{
	int inst, rv, match_minor;
	devpath_t *dptp;
	char *physpath, *drv;
	char *drvinst, *devpath;
	const size_t drvlen = MAXPATHLEN;
	size_t devlen;

	dptp = (devpath_t *)arg;

	assert(dptp->hba_phys != NULL && dptp->dyncomp != NULL);
	assert(dptp->path == NULL);

	/*
	 * Skip stub nodes
	 */
	if (IS_STUB_NODE(node)) {
		return (DI_WALK_CONTINUE);
	}

	errno = 0;

	drv = di_driver_name(node);
	inst = di_instance(node);
	physpath = di_devfs_path(node);
	if (drv == NULL || inst == -1 || physpath == NULL) {
		rv = DI_WALK_CONTINUE;
		goto out;
	}

	devlen = strlen(DEVICES_DIR) + strlen(physpath) + 1;

	devpath = calloc(1, devlen);
	drvinst = calloc(1, drvlen);
	if (devpath == NULL || drvinst == NULL) {
		dptp->l_errno = errno;
		dptp->ret = SCFGA_LIB_ERR;
		rv = DI_WALK_TERMINATE;
		goto out;
	}

	(void) snprintf(drvinst, drvlen, "%s%d", drv, inst);

	/* Create the physical path */
	(void) snprintf(devpath, devlen, "%s%s", DEVICES_DIR, physpath);

	/* Skip node if it is the HBA */
	match_minor = 0;
	if (!dev_cmp(dptp->hba_phys, devpath, match_minor)) {
		rv = DI_WALK_CONTINUE;
		goto out;
	}

	/* Compare the base and dynamic components */
	if (!hba_dev_cmp(dptp->hba_phys, devpath) &&
	    strcmp(dptp->dyncomp, drvinst) == 0) {
		dptp->ret = SCFGA_OK;
		dptp->path = devpath;
		rv = DI_WALK_TERMINATE;
	} else {
		rv =  DI_WALK_CONTINUE;
	}

	/*FALLTHRU*/
out:
	S_FREE(drvinst);
	if (physpath != NULL) di_devfs_path_free(physpath);
	if (dptp->ret != SCFGA_OK) S_FREE(devpath);
	return (rv);
}
Пример #29
0
/*
 * This function is called for every usb minor node.
 * Calls enumerate to assign a logical usb id, and then
 * devfsadm_mklink to make the link.
 */
static int
usb_process(di_minor_t minor, di_node_t node)
{
	devfsadm_enumerate_t rules[1];
	char *l_path, *p_path, *buf, *devfspath;
	char *minor_nm, *drvr_nm, *name = (char *)NULL;
	int i, index;
	int flags = 0;
	int create_secondary_link = 0;

	minor_nm = di_minor_name(minor);
	drvr_nm = di_driver_name(node);
	if ((minor_nm == NULL) || (drvr_nm == NULL)) {
		return (DEVFSADM_CONTINUE);
	}

	devfsadm_print(debug_mid, "usb_process: minor=%s node=%s type=%s\n",
	    minor_nm, di_node_name(node), di_minor_nodetype(minor));

	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_print(debug_mid,
		    "USB_process: devfspath is	NULL\n");
		return (DEVFSADM_CONTINUE);
	}

	l_path = (char *)malloc(PATH_MAX);
	if (l_path == NULL) {
		di_devfs_path_free(devfspath);
		devfsadm_print(debug_mid, "usb_process: malloc() failed\n");
		return (DEVFSADM_CONTINUE);
	}

	p_path = (char *)malloc(PATH_MAX);
	if (p_path == NULL) {
		devfsadm_print(debug_mid, "usb_process: malloc() failed\n");
		di_devfs_path_free(devfspath);
		free(l_path);
		return (DEVFSADM_CONTINUE);
	}

	(void) strcpy(p_path, devfspath);
	(void) strcat(p_path, ":");
	(void) strcat(p_path, minor_nm);
	di_devfs_path_free(devfspath);

	devfsadm_print(debug_mid, "usb_process: path %s\n", p_path);

	for (i = 0; ; i++) {
		if ((driver_name_table[i].driver_name == NULL) ||
		    (strcmp(drvr_nm, driver_name_table[i].driver_name) == 0)) {
			index = driver_name_table[i].index;
			break;
		}
	}

	if (strcmp(di_minor_nodetype(minor), DDI_NT_UGEN) == 0) {
		ugen_create_link(p_path, minor_nm, node, minor);
		free(l_path);
		free(p_path);
		return (DEVFSADM_CONTINUE);
	}

	/* Figure out which rules to apply */
	switch (index) {
	case DRIVER_HUBD:
	case DRIVER_OHCI:
	case DRIVER_EHCI:
	case DRIVER_UHCI:
		rules[0] = hub_rules[0];	/* For HUBs */
		name = "hub";

		break;
	case DRIVER_USB_AC:
		if (strcmp(minor_nm, "sound,audio") == 0) {
			rules[0] = audio_rules[0];
			name = "audio";		/* For audio */
			create_secondary_link = 1;
		} else if (strcmp(minor_nm, "sound,audioctl") == 0) {
			rules[0] = audio_control_rules[0];
			name = "audio-control";		/* For audio */
			create_secondary_link = 1;
		} else if (strcmp(minor_nm, "mux") == 0) {
			rules[0] = audio_mux_rules[0];
			name = "audio-mux";		/* For audio */
		} else {
			free(l_path);
			free(p_path);
			return (DEVFSADM_CONTINUE);
		}
		break;
	case DRIVER_USB_AS:
		rules[0] = audio_stream_rules[0];
		name = "audio-stream";		/* For audio */
		break;
	case DRIVER_VIDEO:
		rules[0] = video_rules[0];
		name = "video";			/* For video */
		create_secondary_link = 1;
		break;
	case DRIVER_HID:
		rules[0] = hid_rules[0];
		name = "hid";			/* For HIDs */
		break;
	case DRIVER_USB_MID:
		rules[0] = device_rules[0];
		name = "device";		/* For other USB devices */
		break;
	case DRIVER_DDIVS_USBC:
		rules[0] = ddivs_usbc_rules[0];
		name = "device";		/* For other USB devices */
		break;
	case DRIVER_SCSA2USB:
		rules[0] = mass_storage_rules[0];
		name = "mass-storage";		/* For mass-storage devices */
		break;
	case DRIVER_USBPRN:
		rules[0] = usbprn_rules[0];
		name = "printer";
		break;
	case DRIVER_HWAHC:
		if (strcmp(minor_nm, "hwahc") == 0) {
			rules[0] = whost_rules[0];
			name = "whost";		/* For HWA HC */
		} else if (strcmp(minor_nm, "hubd") == 0) {
			rules[0] = hub_rules[0];
			name = "hub";		/* For HWA HC */
		} else {
			free(l_path);
			free(p_path);
			return (DEVFSADM_CONTINUE);
		}
		break;
	case DRIVER_HWARC:
		rules[0] = hwarc_rules[0];
		name = "hwarc";		/* For UWB HWA Radio Controllers */
		break;
	case DRIVER_WUSB_CA:
		rules[0] = wusb_ca_rules[0];
		name = "wusb_ca";	/* for wusb cable association */
		break;
	default:
		devfsadm_print(debug_mid, "usb_process: unknown driver=%s\n",
		    drvr_nm);
		free(l_path);
		free(p_path);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 *  build the physical path from the components.
	 *  find the logical usb id, and stuff it in buf
	 */
	if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) {
		devfsadm_print(debug_mid, "usb_process: exit/continue\n");
		free(l_path);
		free(p_path);
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(l_path, PATH_MAX, "usb/%s%s", name, buf);

	devfsadm_print(debug_mid, "usb_process: p_path=%s buf=%s\n",
	    p_path, buf);

	free(buf);

	devfsadm_print(debug_mid, "mklink %s -> %s\n", l_path, p_path);

	(void) devfsadm_mklink(l_path, node, minor, flags);

	if (create_secondary_link) {
		/*
		 * Create secondary links to make newly hotplugged
		 * usb audio device the primary device.
		 */
		if (strcmp(name, "audio") == 0) {
			(void) devfsadm_secondary_link("audio", l_path, 0);
		} else if (strcmp(name, "audio-control") == 0) {
			(void) devfsadm_secondary_link("audioctl", l_path, 0);
		} else if (strcmp(name, "video") == 0) {
			(void) devfsadm_secondary_link(l_path + 4, l_path, 0);
		}
	}

	free(p_path);
	free(l_path);

	return (DEVFSADM_CONTINUE);
}
Пример #30
0
/*ARGSUSED*/
static int
devfs_entry(di_node_t node, di_minor_t minor, void *arg)
{
	char		*devfspath;
	char		resource[MAXPATHLEN];
	char		dev[MAXNAMELEN];
	datalink_id_t	linkid;
	char		*drv;
	char		*cp;
	net_cache_t	*probe;

	cp = di_minor_nodetype(minor);
	if ((cp == NULL) || (strcmp(cp, DDI_NT_NET))) {
		/* doesn't look like a network device */
		return (DI_WALK_CONTINUE);
	}

	drv = di_driver_name(node);
	if (drv == NULL) {
		/* what else can we do? */
		return (DI_WALK_CONTINUE);
	}

	devfspath = di_devfs_path(node);
	if (!devfspath) {
		/* no devfs path?!? */
		rcm_log_message(RCM_DEBUG, _("NET: missing devfs path\n"));
		return (DI_WALK_CONTINUE);
	}

	if (strncmp("/pseudo", devfspath, strlen("/pseudo")) == 0) {
		/* ignore pseudo devices, probably not really NICs */
		rcm_log_message(RCM_DEBUG,
		    _("NET: ignoring pseudo device %s\n"), devfspath);
		di_devfs_path_free(devfspath);
		return (DI_WALK_CONTINUE);
	}

	(void) snprintf(resource, sizeof (resource), "/devices%s", devfspath);
	di_devfs_path_free(devfspath);

	(void) snprintf(dev, sizeof (dev), "%s%d", drv, di_instance(node));
	if (dladm_dev2linkid(dld_handle, dev, &linkid) != DLADM_STATUS_OK) {
		rcm_log_message(RCM_DEBUG,
		    _("NET: failed to find the linkid for %s\n"), dev);
		return (DI_WALK_CONTINUE);
	}

	probe = cache_lookup(resource);
	if (probe != NULL) {
		rcm_log_message(RCM_DEBUG,
		    _("NET: %s already registered (linkid %u)\n"),
		    resource, linkid);
		probe->linkid = linkid;
		probe->flags &= ~(CACHE_STALE);
	} else {
		rcm_log_message(RCM_DEBUG,
		    _("NET: %s is new resource (linkid %u)\n"),
		    resource, linkid);
		probe = calloc(1, sizeof (net_cache_t));
		if (!probe) {
			rcm_log_message(RCM_ERROR, _("NET: malloc failure"));
			return (DI_WALK_CONTINUE);
		}

		probe->resource = strdup(resource);
		probe->linkid = linkid;

		if (!probe->resource) {
			free_node(probe);
			return (DI_WALK_CONTINUE);
		}

		probe->flags |= CACHE_NEW;
		cache_insert(probe);
	}

	return (DI_WALK_CONTINUE);
}