Esempio n. 1
0
static int
dm(di_minor_t minor, di_node_t node)
{
	dev_t	dev;
	minor_t	minorno;
	char	minorname[MAXNAMELEN + 1];
	char	dmname[MAXNAMELEN + 1];
	char	blkname[MAXNAMELEN + 1];
	char	rawname[MAXNAMELEN + 1];
	char	path[PATH_MAX + 1];

	(void) strcpy(minorname, di_minor_name(minor));
	dev = di_minor_devt(minor);
	minorno = minor(dev);

	/* Is it a control node ? */
	if ((minorno == 0) && (strcmp(minorname, "ctl") == 0)) {
		(void) devfsadm_mklink(DM_CONTROL_NODE, node, minor, 0);
		(void) devfsadm_secondary_link(DM_CONTROL_LINUX,
		    DM_CONTROL_NODE, 0);
		return (DEVFSADM_CONTINUE);
	}

	/* If we got here that is not a control node */
	(void) strlcpy(dmname, sizeof (dmname), minorname);
	
	(void) snprintf(blkname, sizeof (blkname), "%s,blk", minorname);
	(void) snprintf(rawname, sizeof (rawname), "%s,raw", minorname);

		if (strcmp(mn, blkname) == 0) {
			(void) snprintf(path, sizeof (path), "%s/%s",
			    DM_BLOCK_NAME, blkname);
		} else if (strcmp(mn, rawname) == 0) {
			(void) snprintf(path, sizeof (path), "%s/%s",
			    DM_CHAR_NAME, blkname);
		} else {
			return (DEVFSADM_CONTINUE);
		}

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

	return (DEVFSADM_CONTINUE);
}
/*
 * Handles minor node type "ddi_display".
 *
 * type=ddi_display fbs/\M0 fb\N0
 */
static int
display(di_minor_t minor, di_node_t node)
{
	char l_path[PATH_MAX + 1], contents[PATH_MAX + 1], *buf;
	devfsadm_enumerate_t rules[1] = {"^fb([0-9]+)$", 1, MATCH_ALL};
	char *mn = di_minor_name(minor);

	/* create fbs/\M0 primary link */
	(void) strcpy(l_path, "fbs/");
	(void) strcat(l_path, mn);
	(void) devfsadm_mklink(l_path, node, minor, 0);

	/* create fb\N0 which links to fbs/\M0 */
	if (devfsadm_enumerate_int(l_path, 0, &buf, rules, 1)) {
		return (DEVFSADM_CONTINUE);
	}
	(void) strcpy(contents, l_path);
	(void) strcpy(l_path, "fb");
	(void) strcat(l_path, buf);
	free(buf);
	(void) devfsadm_secondary_link(l_path, contents, 0);
	return (DEVFSADM_CONTINUE);
}
/*
 * 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);
}
Esempio n. 4
0
/*
 * For the admin device:
 *	/dev/md/admin -> /devices/pseudo/md@0:admin
 *
 * For metadevice:
 *	/dev/md/dsk/foobar --> /devices/pseudo/md@0:0,100,blk
 *	/dev/md/rdsk/foobar --> /devices/pseudo/md@0:0,100,raw
 *
 * Where 'foobar' is user specified arbitrary name and '100'
 * is the minor number returned by MD_IOCMAKE_DEV ioctl
 *
 */
static int
md_create(di_minor_t minor, di_node_t node)
{
	char mn[MAXNAMELEN + 1];
	char path[PATH_MAX + 1];
	char set_path[PATH_MAX +1];
	char sym_path[PATH_MAX + 1];
	int set = -1, ret;
	char *type, *dir;
	char *device_name;
	dev_t minor_devt = di_minor_devt(minor);
	int key;
	mdsetname_t	*sp = NULL;
	md_error_t ep;

	/*
	 * Initialize sdssc entry points. Don't worry about the return
	 * value here since the interface functions will get initialized
	 * correctly regardless.
	 */
	(void) sdssc_bind_library();

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

	/*
	 * Check whether we are being requested to setup the admin
	 * device link or one of the metadevice links. They need
	 * to be treated differently.
	 */

	if (strcmp(mn, "admin") == 0) {
		/* there is only one admin link and always in /dev/md/admin */
		(void) devfsadm_mklink("md/admin", node, minor, 0);
	} else {
		/*
		 * Extract out the minor components and create the
		 * appropriate links. The node looks like:
		 * md@<set>,<mdev>,<type>
		 * where the <set> number is the named diskset,
		 * <mdev> is the metadevice number, and <type>
		 * is the trailing "blk" or "raw" indication.
		 *
		 * NOTE: when <set> is non-zero, we need to create
		 * under the "shared" directory entry instead of linking
		 * into the top level dsk/rdsk directories.
		 */
		ret = sscanf(mn, "%d,", &set);
		if (ret == 1 && (type = strrchr(mn, ',')) != NULL) {
			type++;
			if (strcmp(type, "blk") == 0) {
				dir = "dsk";
			} else {
				dir = "rdsk";
			}

			(void) memset(&ep, '\0', sizeof (ep));
			if ((device_name = meta_getnmentbydev(set,
			    MD_SIDEWILD, minor_devt, NULL, NULL,
			    &key, &ep)) == NULL) {
				(void) close_admin(&ep);
				return (DEVFSADM_CONTINUE);
			}

			if (set == 0) {
				/* this is a simple md */
				(void) snprintf(path, sizeof (path),
				    "md/%s/%s", dir, basename(device_name));
			} else {
				/* this is a shared md */
				(void) snprintf(path, sizeof (path),
				    "md/shared/%d/%s/%s", set, dir,
				    basename(device_name));

				/*
				 * flush the caches so the next call to
				 * metasetnosetname will get us the
				 * updated cache.
				 */
				metaflushnames(0);
				if ((sp = metasetnosetname(set, &ep))
				    != NULL) {
					(void) snprintf(set_path,
					    sizeof (set_path), "md/shared/%d",
					    sp->setno);
					(void) snprintf(sym_path,
					    sizeof (sym_path), "md/%s",
					    sp->setname);
				}
			}
			(void) devfsadm_mklink(path, node, minor, 0);
			Free(device_name);

			if (sp != NULL) {
				(void) devfsadm_secondary_link(sym_path,
				    set_path, 0);
			}
		}
	}

	(void) close_admin(&ep);
	return (DEVFSADM_CONTINUE);
}