예제 #1
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);
}
예제 #2
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);
}
예제 #3
0
/*
 * According to devfs path name, it will print device node name.
 */
static void
print_node_name(char *drv_name, char *strdevfspath)
{
	di_node_t	curnode;
	char *devfspath = NULL;
	char *node_name = NULL;

	curnode = di_drv_first_node(drv_name, devinfo_root);
	for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
		devfspath = di_devfs_path(curnode);
		logmsg(MSG_INFO, "find: devfspath %s\n", devfspath);

		if (devfspath == NULL)
			continue;

		if ((strlen(strdevfspath) == strlen(devfspath)) &&
		    (strncmp(strdevfspath, devfspath,
		    strlen(devfspath)) == 0)) {
			node_name = find_link(curnode);
			if (node_name == NULL) {
				(void) printf("NOT MAPPED\n");
			} else {
				(void) printf("%s\n", node_name);
			}
			return;
		}
	}
}
예제 #4
0
/*
 * Handles:
 *	/dev/av/[0-9]+/(async|isoch)
 */
static int
av_create(di_minor_t minor, di_node_t node)
{
	devfsadm_enumerate_t rules[1] = {"^av$/^([0-9]+)$", 1, MATCH_ADDR};
	char	*minor_str;
	char	path[PATH_MAX + 1];
	char	*buf;

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

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

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

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

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

	return (DEVFSADM_CONTINUE);
}
예제 #5
0
파일: port_link.c 프로젝트: alhazred/onarm
/*
 * Onboard dialout devices
 * Creates links of the form "/dev/cua/[a..z]"
 */
static int
onbrd_dialout_create(di_minor_t minor, di_node_t node)
{
	char l_path[MAXPATHLEN], p_path[MAXPATHLEN];
	char  *devfspath, *buf, *mn;

	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_errprint("%s: di_devfs_path() failed\n", modname);
		return (DEVFSADM_CONTINUE);
	}

	if ((mn = di_minor_name(minor)) == NULL) {
		devfsadm_errprint("%s: NULL minor name\n\t%s\n",
		    modname, devfspath);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 * verify this is a dialout port
	 */
	if (!is_dialout(mn)) {
		devfsadm_errprint("%s: not a dialout device\n\t%s:%s\n",
		    modname, devfspath, mn);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

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

	buf = NULL;

#ifdef __i386
	buf = check_compat_ports(p_path, mn);
#endif

	/*
	 * devfsadm_enumerate_char_start() is a private interface
	 * for use by the ports module only.
	 */
	if (!buf && devfsadm_enumerate_char_start(p_path, 0, &buf, obport_rules,
	    1, start_id)) {
		devfsadm_errprint("%s: devfsadm_enumerate_char_start() failed"
		    "\n\t%s\n", modname, p_path);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 * create the logical link
	 */
	(void) strcpy(l_path, "cua/");
	(void) strcat(l_path, buf);
	(void) devfsadm_mklink(l_path, node, minor, 0);
	free(buf);
	return (DEVFSADM_CONTINUE);
}
예제 #6
0
static int
ses_callback(di_minor_t minor, di_node_t node)
{
	char l_path[PATH_MAX];
	char *buf;
	char *devfspath;
	char p_path[PATH_MAX];
	devfsadm_enumerate_t re[] = {"^es$/^ses([0-9]+)$", 1, MATCH_ALL};

	/* find devices path -- need to free mem */
	if (NULL == (devfspath = di_devfs_path(node))) {
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath,
	    di_minor_name(minor));


	/* find next number to use; buf is an ascii number */
	if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) {
		/* free memory */
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	(void) snprintf(l_path, sizeof (l_path), "es/ses%s", buf);

	(void) devfsadm_mklink(l_path, node, minor, 0);
	/* free memory */
	free(buf);
	di_devfs_path_free(devfspath);
	return (DEVFSADM_CONTINUE);

}
예제 #7
0
/*
 * Handles minor node type "ddi_parallel".
 * type=ddi_parallel;name=mcpp     mcpp\N0
 */
static int
parallel(di_minor_t minor, di_node_t node)
{
	char path[PATH_MAX + 1], *buf;
	devfsadm_enumerate_t rules[1] = {"mcpp([0-9]+)$", 1, MATCH_ALL};


	if (strcmp(di_node_name(node), "mcpp") != 0) {
		return (DEVFSADM_CONTINUE);
	}

	if (NULL == (buf = di_devfs_path(node))) {
		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), "mcpp%s", buf);
	free(buf);

	(void) devfsadm_mklink(path, node, minor, 0);
	return (DEVFSADM_CONTINUE);
}
예제 #8
0
static int
fc_port(di_minor_t minor, di_node_t node)
{
	devfsadm_enumerate_t rules[1] = {"fc/fp([0-9]+)$", 1, MATCH_ALL};
	char *buf, path[PATH_MAX + 1];
	char *ptr;

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

	(void) strcpy(path, ptr);
	(void) strcat(path, ":");
	(void) strcat(path, di_minor_name(minor));

	di_devfs_path_free(ptr);

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

	(void) strcpy(path, "fc/fp");
	(void) strcat(path, buf);
	free(buf);

	(void) devfsadm_mklink(path, node, minor, 0);
	return (DEVFSADM_CONTINUE);
}
예제 #9
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);
}
예제 #10
0
/*
 * Converts a libdevinfo node into a /devices path.  Caller must free results.
 */
static char *
get_rsrcname(di_node_t dinode)
{
	int len;
	char *rsrcname;
	char *devfspath;
	char name[MAXPATHLEN];

	if ((devfspath = di_devfs_path(dinode)) == NULL) {
		rcm_log_message(RCM_ERROR, "MPXIO: resource has null path.\n");
		return (NULL);
	}

	len = snprintf(name, sizeof (name), "/devices%s", devfspath);
	di_devfs_path_free(devfspath);
	if (len >= sizeof (name)) {
		rcm_log_message(RCM_ERROR, "MPXIO: resource path too long.\n");
		return (NULL);
	}

	if ((rsrcname = strdup(name)) == NULL)
		rcm_log_message(RCM_ERROR,
		    "MPXIO: failed to allocate resource name (%s).\n",
		    strerror(errno));

	return (rsrcname);
}
예제 #11
0
static int
mc_node(di_minor_t minor, di_node_t node)
{
	char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath;
	char *minor_nm;

	minor_nm = di_minor_name(minor);

	if (minor_nm == NULL) {
		return (DEVFSADM_CONTINUE);
	}

	devfspath = di_devfs_path(node);

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

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

	(void) strcpy(l_path, "mc/mc");
	(void) strcat(l_path, buf);

	free(buf);

	(void) devfsadm_mklink(l_path, node, minor, 0);
	return (DEVFSADM_CONTINUE);
}
예제 #12
0
파일: port_link.c 프로젝트: alhazred/onarm
/*
 * PCMCIA dialout serial ports
 * Creates links of the form "/dev/cua/pcN", where N is the PCMCIA
 * socket number the device is plugged into.
 */
static int
pcmcia_dialout_create(di_minor_t minor, di_node_t node)
{
	char l_path[MAXPATHLEN];
	char  *devfspath;
	int socket, *intp;

	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_errprint("%s: di_devfs_path() failed\n", modname);
		return (DEVFSADM_TERMINATE);
	}

	if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "socket", &intp) <= 0) {
		devfsadm_errprint("%s: failed socket lookup\n\t%s\n",
		    modname, devfspath);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_TERMINATE);
	}

	socket = PCMCIA_SOCKETNO(*intp);

	di_devfs_path_free(devfspath);
	(void) sprintf(l_path, "cua/pc%d", socket);
	(void) devfsadm_mklink(l_path, node, minor, 0);

	return (DEVFSADM_TERMINATE);
}
예제 #13
0
파일: port_link.c 프로젝트: alhazred/onarm
/*
 * Lights Out Management (LOM) serial ports
 * Creates links of the form "/dev/term/lom-console".
 */
static int
lom_port_create(di_minor_t minor, di_node_t node)
{
	char  *devfspath;
	char  *minor_name;

	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_errprint("%s: di_devfs_path() failed\n", modname);
		return (DEVFSADM_CONTINUE);
	}

	if ((minor_name = di_minor_name(minor)) == NULL) {
		devfsadm_errprint("%s: NULL minor name\n\t%s\n",
		    modname, devfspath);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 * if this is the LOM console serial port (i.e. the minor
	 * name == lom-console ), create /dev/term/lom-console link and
	 * then we are done with this node.
	 */
	if (strcmp(minor_name, "lom-console") == 0) {
		(void) devfsadm_mklink("term/lom-console", node, minor, 0);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_TERMINATE);
	}

	/* This is not a LOM node, continue... */
	di_devfs_path_free(devfspath);
	return (DEVFSADM_CONTINUE);
}
예제 #14
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);
}
/*
 * Discover an HBA node with  matching path.
 * The di_node_t argument should be the root of the device tree.
 * This routine assumes the locks have been taken
 */
static int
find_matching_hba(di_node_t node, void *arg)
{
	int *propData, rval;
	walkarg_t *wa = (walkarg_t *)arg;
	char	*devpath, fulldevpath[MAXPATHLEN];

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

	rval = di_prop_lookup_ints(DDI_DEV_T_ANY, node,
	    "sm-hba-supported", &propData);
	if (rval < 0) {
		return (DI_WALK_CONTINUE);
	} else {
		if ((devpath = di_devfs_path(node)) == NULL) {
			/* still continue to see if there is matching one. */
			return (DI_WALK_CONTINUE);
		}
		(void) snprintf(fulldevpath, MAXPATHLEN, "%s%s", DEVICES_DIR,
		    devpath);

		if ((strstr(fulldevpath, wa->devpath)) != NULL) {
				*wa->flag = B_TRUE;
			/* Found a node. No need to walk any more. */
			di_devfs_path_free(devpath);
			return (DI_WALK_TERMINATE);
		}
		di_devfs_path_free(devpath);
	}

	return (DI_WALK_CONTINUE);
}
예제 #16
0
static int
niu_asru_set(tnode_t *tn, di_node_t dn, topo_mod_t *mod)
{
	char *path;
	nvlist_t *fmri;
	int e;

	if ((path = di_devfs_path(dn)) != NULL) {
		fmri = topo_mod_devfmri(mod, FM_DEV_SCHEME_VERSION, path, NULL);
		if (fmri == NULL) {
			topo_mod_dprintf(mod,
			    "dev:///%s fmri creation failed.\n", path);
			di_devfs_path_free(path);
			return (-1);
		}
		di_devfs_path_free(path);
	} else {
		topo_mod_dprintf(mod, "NULL di_devfs_path.\n");
		if (topo_prop_get_fmri(tn, TOPO_PGROUP_PROTOCOL,
		    TOPO_PROP_RESOURCE, &fmri, &e) < 0)
			return (topo_mod_seterrno(mod, e));
	}
	if (topo_node_asru_set(tn, fmri, 0, &e) < 0) {
		nvlist_free(fmri);
		return (topo_mod_seterrno(mod, e));
	}
	nvlist_free(fmri);
	return (0);
}
예제 #17
0
static int
create_children(mmd_t *mdp,
    di_prom_handle_t ph, md_node_t *md_parent, di_node_t di_parent)
{
	md_node_t	*md_node;
	md_node_t	*md_child;
	di_node_t	di_child;
	char		*path;
	int		rv;

	path = di_devfs_path(di_parent);
	if (path == NULL)
		return (EIO);

	md_node = link_device_node(mdp, ph, di_parent, md_parent, path);
	di_devfs_path_free(path);
	if (md_node == NULL) {
		return (ENOMEM);
	}

	while ((di_child = di_child_node(di_parent)) != DI_NODE_NIL) {
		path = di_devfs_path(di_child);
		if (path != NULL) {
			md_child = link_device_node(mdp,
			    ph, di_child, md_node, path);
			di_devfs_path_free(path);
			if (md_child == NULL) {
				return (ENOMEM);
			}
		}

		rv = create_peers(mdp, ph, md_node, di_child);
		if (rv != 0)
			return (rv);

		md_node = md_child;
		di_parent = di_child;
	}
	return (0);
}
예제 #18
0
int
wrsm(di_minor_t minor, di_node_t node)
{
	const char *node_name = di_node_name(node);
	const char *minor_name = di_minor_name(minor);
	char path[PATH_MAX + 1];

	if (minor_name == NULL || node_name == NULL) {
		return (DEVFSADM_CONTINUE);
	}
	if (strcmp(minor_name, "admin") == 0) {
		/* admin pseudo device */
		(void) snprintf(path, sizeof (path), "%s%s", node_name,
		    minor_name);
	} else if (strcmp(minor_name, "ctrl") == 0) {
		/* controller pseudo device */
		dev_t dev = di_minor_devt(minor);
		minor_t dev_minor = minor(dev);
		(void) snprintf(path, sizeof (path), "%s%u", node_name,
		    (uint_t)dev_minor);
	} else {
		/*
		 * For hardware devices, the devlink must be
		 * /dev/<node_name><portid>. devpath is of the format
		 * ".../<node_name>@<portid>,0". Need to extract the
		 * <portid> for use in bulding devlink.
		 */
		char devpath[PATH_MAX + 1];
		char *devfs_path;
		int i;

		devfs_path = di_devfs_path(node);
		if (devfs_path == NULL) {
			return (DEVFSADM_CONTINUE);
		}
		(void) strcpy(devpath, devfs_path);
		di_devfs_path_free(devfs_path);

		for (i = strlen(devpath); devpath[i] != '@' && i > 0; i--) {
			if (devpath[i] == ',') {
				devpath[i] = 0;
			}
		}
		if (i == 0) {
			return (DEVFSADM_CONTINUE);
		}
		(void) snprintf(path, sizeof (path), "wci%s", &devpath[i+1]);
	}
	(void) devfsadm_mklink(path, node, minor, 0);

	return (DEVFSADM_CONTINUE);
}
예제 #19
0
파일: port_link.c 프로젝트: alhazred/onarm
/*
 * Called for all dialout devices that are NOT onboard
 * Creates links of the form "/dev/cua/[0..n]"
 */
static int
dialout_create(di_minor_t minor, di_node_t node)
{
	char l_path[MAXPATHLEN], p_path[MAXPATHLEN];
	char  *devfspath, *buf, *mn;

	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_errprint("%s: di_devfs_path() failed\n", modname);
		return (DEVFSADM_CONTINUE);
	}

	if ((mn = di_minor_name(minor)) == NULL) {
		devfsadm_errprint("%s: NULL minorname\n\t%s\n",
		    modname, devfspath);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	if (!is_dialout(mn)) {
		devfsadm_errprint("%s: invalid minor name\n\t%s:%s\n",
		    modname, devfspath, mn);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

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

	if (devfsadm_enumerate_int(p_path, 0, &buf, port_rules, 1)) {
		devfsadm_errprint("%s:dialout_create:"
		    " enumerate_int() failed\n\t%s\n",
		    modname, p_path);
		return (DEVFSADM_CONTINUE);
	}
	(void) strcpy(l_path, "cua/");
	(void) strcat(l_path, buf);

	/*
	 *  add the minor name to the physical path so we can create
	 *  the link.
	 */
	(void) devfsadm_mklink(l_path, node, minor, 0);

	free(buf);
	return (DEVFSADM_CONTINUE);
}
예제 #20
0
/*
 * Callback used by path2node().
 */
static int
p2n_cb(di_node_t node, void *arg)
{
	int	ret = DI_WALK_CONTINUE;
	cb_t	*cbp = arg;
	char	*phys_path = di_devfs_path(node);

	if (strcmp(cbp->cb_path, phys_path) == 0) {
		cbp->cb_node = node;
		ret = DI_WALK_TERMINATE;
	}
	di_devfs_path_free(phys_path);

	return (ret);
}
예제 #21
0
파일: port_link.c 프로젝트: alhazred/onarm
/*
 * Remote System Controller (RSC) serial ports
 * Creates links of the form "/dev/rsc-control" | "/dev/term/rsc-console".
 */
static int
rsc_port_create(di_minor_t minor, di_node_t node)
{
	char  *devfspath;
	char  *minor_name;


	devfspath = di_devfs_path(node);
	if (devfspath == NULL) {
		devfsadm_errprint("%s: di_devfs_path() failed\n", modname);
		return (DEVFSADM_CONTINUE);
	}

	if ((minor_name = di_minor_name(minor)) == NULL) {
		devfsadm_errprint("%s: NULL minor name\n\t%s\n",
		    modname, devfspath);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 * if this is the RSC console serial port (i.e. the minor name == ssp),
	 * create /dev/term/rsc-console link and then we are done with this
	 * node.
	 */
	if (strcmp(minor_name, "ssp") == 0) {
		(void) devfsadm_mklink("term/rsc-console", node, minor, 0);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_TERMINATE);

	/*
	 * else if this is the RSC control serial port (i.e. the minor name ==
	 * sspctl), create /dev/rsc-control link and then we are done with this
	 * node.
	 */
	} else if (strcmp(minor_name, "sspctl") == 0) {
		(void) devfsadm_mklink("rsc-control", node, minor, 0);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_TERMINATE);
	}

	/* This is not an RSC node, continue... */
	di_devfs_path_free(devfspath);
	return (DEVFSADM_CONTINUE);
}
예제 #22
0
static int
devprop_set(tnode_t *tn, di_node_t dn,
	const char *tpgrp, const char *tpnm, topo_mod_t *mod)
{
	char *path;
	int err, e;

	if ((path = di_devfs_path(dn)) == NULL) {
		topo_mod_dprintf(mod, "NULL di_devfs_path.\n");
		return (topo_mod_seterrno(mod, ETOPO_PROP_NOENT));
	}
	e = topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE,
	    path, &err);
	di_devfs_path_free(path);
	if (e != 0)
		return (topo_mod_seterrno(mod, err));
	return (0);
}
예제 #23
0
static void
print_mpx_capable(di_node_t curnode)
{
	char *prop;
	char *path;
	char *aliases = NULL;

	if (cap_N_option) {
		aliases = calloc(1, MAXPATHLEN + 1);
		if (aliases == NULL) {
			logmsg(MSG_ERROR,
			    gettext("Unable to allocate memory for a device "
			    "alias list\n"));
			return;
		}
	}

	for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
		if (di_prop_lookup_strings(DDI_DEV_T_ANY, curnode,
		    "initiator-port", &prop) >= 0) {
			if ((path = di_devfs_path(curnode)) == NULL) {
				logmsg(MSG_INFO,
				    "Unable to find devfs path for device "
				    "%s: %s\n", &curnode, strerror(errno));
				continue;
			}
			if (cap_N_option) {
				char *nodename = di_node_name(curnode);
				/* nodename is never going to be null */
				if (strstr(aliases, nodename) == NULL)
					/* haven't seen this nodename before */
					(void) snprintf(aliases,
					    MAXPATHLEN + 1, "%s|%s",
					    ((aliases != NULL) ? aliases : ""),
					    nodename);
			} else
				(void) printf("%s\n", path);
		}
	}
	if (cap_N_option)
		(void) printf("%s\n", aliases);
}
예제 #24
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);
}
예제 #25
0
/*
 * Nodes belonging to the configured driver (dtls->fcal_driver) are
 * located in the device tree. A check is applied that any node found has
 * a physical address beginning with the configured search string
 * (dtls->fcal_disk_parent). For each suitable node found, get_drv_info()
 * is called to determine if a change of status has occurred.
 * Returns 1 if any status has changed - else 0.
 */
static int
walk_disks(di_node_t node, led_dtls_t *dtls)
{
	static char *sl_platform_sl = "/platform/";
	int r = 0;
	int len;
	/* find "/platform/" */
	char *ptr = strstr(dtls->fcal_disk_parent, sl_platform_sl);

	if (ptr == NULL)
		return (0);
	/* skip over "/platform" */
	ptr += strlen(sl_platform_sl) - 1;
	len = strlen(ptr);

	for (node = di_drv_first_node(dtls->fcal_driver, node);
	    node != DI_NODE_NIL;
	    node = di_drv_next_node(node)) {
		char *dev_path = di_devfs_path(node);

		if (dev_path == NULL) {
			/* no memory, just hope things get better */
			continue;
		}
		if (memcmp(dev_path, ptr, len) != 0) {
			/*
			 * path name doesn't start right, skip this one
			 */
			free(dev_path);
			continue;
		}
		free(dev_path);
		if (get_drv_info(node, dtls) != 0) {
			r = 1;	/* change observed */
		}
	}

	return (r);
}
예제 #26
0
/*
 * destroy_zfd_devs() and its helper destroy_cb() tears down any zfd instances
 * associated with this zone. If things went very wrong, we might have an
 * incorrect number of instances hanging around.  This routine hunts down and
 * tries to remove all of them. Of course, if the fd is open, the instance will
 * not detach, which is a potential issue.
 */
static int
destroy_cb(di_node_t node, void *arg)
{
	struct cb_data *cb = (struct cb_data *)arg;
	char *prop_data;
	char *tmp;
	char devpath[MAXPATHLEN];
	devctl_hdl_t hdl;

	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zfd_zname",
	    &prop_data) == -1)
		return (DI_WALK_CONTINUE);

	assert(prop_data != NULL);
	if (strcmp(prop_data, zone_name) != 0) {
		/* this is a zfd for a different zone */
		return (DI_WALK_CONTINUE);
	}

	cb->found++;
	tmp = di_devfs_path(node);
	(void) snprintf(devpath, sizeof (devpath), "/devices/%s", tmp);
	di_devfs_path_free(tmp);

	if ((hdl = devctl_device_acquire(devpath, 0)) == NULL) {
		zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, "
		    "but it could not be controlled.", devpath);
		return (DI_WALK_CONTINUE);
	}
	if (devctl_device_remove(hdl) == 0) {
		cb->killed++;
	} else {
		zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, "
		    "but it could not be removed.", devpath);
	}
	devctl_release(hdl);
	return (DI_WALK_CONTINUE);
}
예제 #27
0
/*
 * Handles links of the form:
 * type=ddi_pseudo;name=se;minor2=hdlc	se_hdlc\N0
 * type=ddi_pseudo;name=serial;minor2=hdlc	se_hdlc\N0
 */
static int
se_hdlc_create(di_minor_t minor, di_node_t node)
{
	devfsadm_enumerate_t rules[1] = {"^se_hdlc([0-9]+)$", 1, MATCH_ALL};
	char *buf, path[PATH_MAX + 1];
	char *ptr;
	char *mn;

	mn = di_minor_name(minor);

	/* minor node should be of the form: "?,hdlc" */
	if (strcmp(mn + 1, ",hdlc") != 0) {
		return (DEVFSADM_CONTINUE);
	}

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

	(void) strcpy(path, ptr);
	(void) strcat(path, ":");
	(void) strcat(path, mn);

	di_devfs_path_free(ptr);

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

	(void) strcpy(path, "se_hdlc");
	(void) strcat(path, buf);
	free(buf);

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

	return (DEVFSADM_CONTINUE);
}
예제 #28
0
/*ARGSUSED*/
static int
DEVprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	char *dnpath;
	char *path, *fpath;
	int d, f;
	int err, e;

	mp = did_mod(pd);
	if ((dnpath = di_devfs_path(did_dinode(pd))) == NULL) {
		topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
		return (topo_mod_seterrno(mp, ETOPO_PROP_NOENT));
	}
	if ((path = topo_mod_strdup(mp, dnpath)) == NULL) {
		di_devfs_path_free(dnpath);
		return (-1);
	}
	di_devfs_path_free(dnpath);

	/* The DEV path is modified for hostbridges */
	if (strcmp(topo_node_name(tn), HOSTBRIDGE) == 0) {
		fpath = dev_for_hostbridge(did_mod(pd), path);
	} else {
		did_BDF(pd, NULL, &d, &f);
		fpath = dev_path_fix(mp, path, d, f);
	}
	if (fpath == NULL)
		return (-1);
	e = topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, fpath, &err);
	topo_mod_strfree(mp, fpath);
	if (e != 0)
		return (topo_mod_seterrno(mp, err));
	return (0);
}
예제 #29
0
/*
 * This function is called for every ieee1394 minor node.
 * Calls enumerate to assign a logical ieee1394 id, and then
 * devfsadm_mklink to make the link.
 */
static int
ieee1394_process(di_minor_t minor, di_node_t node)
{
	char *buf, *devfspath;
	char l_path[PATH_MAX], p_path[PATH_MAX];
	devfsadm_enumerate_t re[] = {"^1394/hba([0-9]+)$", 1, MATCH_ALL};

	devfspath = di_devfs_path(node);

	devfsadm_print(debug_mid,
		"ieee1394_process: path %s\n", devfspath);

	(void) snprintf(p_path, sizeof (p_path), "%s:%s",
		devfspath, di_minor_name(minor));
	di_devfs_path_free(devfspath);

	/*
	 *  Build the physical path from the components. Find the logical
	 *  ieee1394 HBA id, and stuff it in buf
	 */
	if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) {
		devfsadm_print(debug_mid, "ieee1394_process: exit/continue\n");
		return (DEVFSADM_CONTINUE);
	}
	devfsadm_print(debug_mid, "ieee1394_process: p_path=%s buf=%s\n",
					p_path, buf);

	(void) snprintf(l_path, sizeof (l_path), "1394/hba%s", buf);

	free(buf);

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

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

	return (DEVFSADM_CONTINUE);
}
예제 #30
0
파일: ucblinks.c 프로젝트: andreiw/polaris
static int
find_sd_nodes(di_node_t node, di_minor_t minor, void *arg)
{
	char	*path;
	char	devpath[MAXPATHLEN];
	struct devices_ent *dep;

	path = di_devfs_path(node);

	if (*path == '/') {
		(void) strcpy(devpath, path+1);
		(void) strcat(devpath, ":");
		(void) strcat(devpath, di_minor_name(minor));

		dep = lookup_devices_sym(devpath);
		if (dep != NULL) {
			dep->issd = 1;
		}
	}

	di_devfs_path_free(path);

	return (DI_WALK_CONTINUE);
}