Esempio n. 1
0
/*
 * add a port monitor entry for device /dev/term/"port"
 */
static void
add_pm_entry(int port)
{
	char cmdline[CMDLEN];
	int sac_exitval;

	add_port_monitor(port);
	(void) sprintf(cmdline,
	    "/usr/sbin/pmadm -a -p ttymon%d -s %d -i root"
	    " -v `/usr/sbin/ttyadm -V` -f*x -y\"/dev/term/%d\""
	    " -m \"`/usr/sbin/ttyadm -d /dev/term/%d -s /usr/bin/login"
	    " -l 9600 -p \\\"login: \\\"`\"", PM_NUM(port), port, port, port);

	if (devfsadm_noupdate() == DEVFSADM_FALSE) {
		sac_exitval = execute(cmdline);
		if ((sac_exitval != 0) && (sac_exitval != E_SACNOTRUN)) {
			devfsadm_print(VERBOSE_MID,
			    "failed to add port monitor entry"
			    " for /dev/term/%d\n", port);
			devfsadm_print(VERBOSE_MID, "pmadm: (%s) %s\n",
			    SAC_EID(sac_exitval), SAC_EMSG(sac_exitval));
		}
	}
	pma[port].flags |= PM_HAS_ENTRY;
	devfsadm_print(VERBOSE_MID, "%s: /dev/term/%d added to sacadm\n",
	    modname, port);
}
Esempio n. 2
0
static void
add_port_monitor(int port)
{
	char cmdline[CMDLEN];
	int sac_exitval;

	if ((pma[PM_SLOT(port)].flags & HAS_PORT_MON) != 0) {
		return;
	}

	(void) sprintf(cmdline,
	    "/usr/sbin/sacadm -l -p ttymon%d", PM_NUM(port));
	sac_exitval = execute(cmdline);
	if (sac_exitval == E_NOEXIST) {
		(void) sprintf(cmdline,
		    "/usr/sbin/sacadm -a -n 2 -p ttymon%d -t ttymon"
		    " -c /usr/lib/saf/ttymon -v \"`/usr/sbin/ttyadm"
		    " -V`\" -y \"Ports %d-%d\"", PM_NUM(port), PM_SLOT(port),
		    PM_SLOT(port) + (PM_GRPSZ - 1));
		if (devfsadm_noupdate() == DEVFSADM_FALSE) {
			if (sac_exitval = execute(cmdline)) {
				devfsadm_print(VERBOSE_MID,
				    "failed to add port monitor ttymon%d\n",
				    PM_NUM(port));
				devfsadm_print(VERBOSE_MID, "sacadm: (%s) %s\n",
				    SAC_EID(sac_exitval),
				    SAC_EMSG(sac_exitval));
			}
		}
		devfsadm_print(VERBOSE_MID, "%s: port monitor ttymon%d added\n",
		    modname, PM_NUM(port));
	}
	pma[PM_SLOT(port)].flags |= HAS_PORT_MON;
}
Esempio n. 3
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);
}
static void
ugen_create_link(char *p_path, char *node_name,
    di_node_t node, di_minor_t minor)
{
	char *buf, s[MAXPATHLEN];
	char *lasts = s;
	char *vid, *pid;
	char *minor_name;
	char ugen_RE[128];
	devfsadm_enumerate_t ugen_rules[1];
	char l_path[PATH_MAX];
	int flags = 0;

	devfsadm_print(debug_mid, "ugen_create_link: p_path=%s name=%s\n",
	    p_path, node_name);

	(void) strlcpy(s, node_name, sizeof (s));

	/* get vid, pid and minor name strings */
	vid = strtok_r(lasts, ".", &lasts);
	pid = strtok_r(NULL, ".", &lasts);
	minor_name = lasts;

	if ((vid == NULL) || (pid == NULL) || (minor_name == NULL)) {
		return;
	}

	/* create regular expression contain vid and pid */
	(void) snprintf(ugen_RE, sizeof (ugen_RE),
	    "^usb$/^%s\\.%s$/^([0-9]+)$", vid, pid);
	devfsadm_print(debug_mid,
	    "ugen_create_link: ugen_RE=%s minor_name=%s\n",
	    ugen_RE, minor_name);

	bzero(ugen_rules, sizeof (ugen_rules));

	ugen_rules[0].re = ugen_RE;
	ugen_rules[0].subexp = 1;
	ugen_rules[0].flags = MATCH_ADDR;

	/*
	 *  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, ugen_rules, 1)) {
		devfsadm_print(debug_mid, "ugen_create_link: exit/continue\n");
		return;
	}

	(void) snprintf(l_path, sizeof (l_path), "usb/%s.%s/%s/%s",
	    vid, pid, buf, minor_name);

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

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

	free(buf);
}
Esempio n. 5
0
int
minor_init()
{
	devfsadm_print(disk_mid,
	    "%s: minor_init(): Creating disks reserved ID cache\n",
	    modname);
	return (devfsadm_reserve_id_cache(disks_re_array, NULL));
}
Esempio n. 6
0
/*
 * fork and exec a command, waiting for the command to
 * complete and return it's status
 */
static int
execute(const char *s)
{
	int	status;
	int	fd;
	pid_t	pid;
	pid_t	w;

	/*
	 * fork a single threaded child proc to execute the
	 * sacadm command string
	 */
	devfsadm_print(PORT_MID, "%s: execute:\n\t%s\n", modname, s);
	if ((pid = fork1()) == 0) {
		(void) close(0);
		(void) close(1);
		(void) close(2);
		fd = open("/dev/null", O_RDWR);
		(void) dup(fd);
		(void) dup(fd);
		(void) execl("/sbin/sh", "sh", "-c", s, 0);
		/*
		 * return the sacadm exit status (see _exit(2))
		 */
		_exit(127);
	}

	/*
	 * wait for child process to terminate
	 */
	for (;;) {
		w = wait(&status);
		if (w == pid) {
			devfsadm_print(PORT_MID, "%s:exit status (%d)\n",
			    modname, SAC_EXITVAL(status));
			return (SAC_EXITVAL(status));
		}
		if (w == (pid_t)-1) {
			devfsadm_print(VERBOSE_MID, "%s: exec failed\n",
						modname);
			return (-1);
		}
	}

	/* NOTREACHED */
}
Esempio n. 7
0
/*
 * delete_port_monitor()
 * Check for the existence of a port monitor for "port" and remove it if
 * one exists
 */
static void
delete_port_monitor(int port)
{
	char	cmdline[CMDLEN];
	int	sac_exitval;

	(void) sprintf(cmdline, "/usr/sbin/sacadm -L -p ttymon%d",
	    PM_NUM(port));
	sac_exitval = execute(cmdline);

	/* clear the PM tag and return if the port monitor is not active */
	if (sac_exitval == E_NOEXIST) {
		pma[PM_SLOT(port)].flags &= ~HAS_PORT_MON;
		return;
	}

	/* some other sacadm(1m) error, log and return */
	if (sac_exitval != 0) {
		devfsadm_print(VERBOSE_MID, "sacadm: (%s) %s\n",
		    SAC_EID(sac_exitval), SAC_EMSG(sac_exitval));
		return;
	}

	if (devfsadm_noupdate() == DEVFSADM_FALSE) {
		(void) sprintf(cmdline,
		    "/usr/sbin/sacadm -r -p ttymon%d", PM_NUM(port));
		if (sac_exitval = execute(cmdline)) {
			devfsadm_print(VERBOSE_MID,
			    "failed to remove port monitor ttymon%d\n",
			    PM_NUM(port));
			devfsadm_print(VERBOSE_MID, "sacadm: (%s) %s\n",
			    SAC_EID(sac_exitval), SAC_EMSG(sac_exitval));
		}
	}
	devfsadm_print(VERBOSE_MID, "%s: port monitor ttymon%d removed\n",
	    modname, PM_NUM(port));
	pma[PM_SLOT(port)].flags &= ~HAS_PORT_MON;
}
Esempio n. 8
0
static void
remove_pm_entry(char *pmtag, int port)
{

	char cmdline[CMDLEN];
	int sac_exitval;

	if (devfsadm_noupdate() == DEVFSADM_FALSE) {
		(void) snprintf(cmdline, sizeof (cmdline),
		    "/usr/sbin/pmadm -r -p %s -s %d", pmtag, port);
		sac_exitval = execute(cmdline);
		if ((sac_exitval != 0) && (sac_exitval != E_SACNOTRUN)) {
			devfsadm_print(VERBOSE_MID,
			    "failed to remove port monitor entry"
			    " for /dev/term/%d\n", port);
			devfsadm_print(VERBOSE_MID, "pmadm: (%s) %s\n",
			    SAC_EID(sac_exitval), SAC_EMSG(sac_exitval));
		}
	}
	pma[port].flags &= ~PM_HAS_ENTRY;
	devfsadm_print(VERBOSE_MID, "%s: /dev/term/%d removed from sacadm\n",
	    modname, port);
}
Esempio n. 9
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);
}
Esempio n. 10
0
/*
 * parse port number from string
 * returns port number if in range [0..maxports]
 */
static int
parse_portno(char *dname)
{
	int pn;

	if (sscanf(dname, "%d", &pn) != 1)
		return (-1);

	if ((pn < 0) || (pn > maxports)) {
		devfsadm_print(VERBOSE_MID,
		    "%s:parse_portno: %d not in range (0..%d)\n",
		    modname, pn, maxports);
		return (-1);
	}

	return (pn);
}
Esempio n. 11
0
int
minor_init()
{
	char *maxport_str;

	maxport_str = defread("SUNW_port_link.maxports");

	if ((maxport_str == NULL) ||
	    (sscanf(maxport_str, "%d", &maxports) != 1))
		maxports = MAXPORTS_DEFAULT;

	devfsadm_print(CHATTY_MID, "%s: maximum number of port devices (%d)\n",
	    modname, maxports);

	if (pma_alloc() == NULL)
		return (DEVFSADM_FAILURE);

	return (DEVFSADM_SUCCESS);
}
Esempio n. 12
0
/*
 * Removes port entries that no longer have devices
 * backing them
 * Schedules an update the sacadm (portmon) database
 */
static void
rm_dangling_port(char *devname)
{
	char *portstr;
	int  portnum;

	devfsadm_print(PORT_MID, "%s:rm_stale_port: %s\n",
	    modname, devname);

	if ((portstr = strrchr(devname, (int)'/')) == NULL) {
		devfsadm_errprint("%s: invalid name: %s\n",
		    modname, devname);
		return;
	}
	portstr++;

	/*
	 * mark for removal from sacadm database
	 */
	if ((portnum = parse_portno(portstr)) != -1)
		pma[portnum].flags |= PORT_REMOVED;

	devfsadm_rm_all(devname);
}
Esempio n. 13
0
int
minor_fini(void)
{
	devfsadm_print(debug_mid, "ramdisk_link: minor_fini\n");
	return (DEVFSADM_SUCCESS);
}
Esempio n. 14
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);
}
Esempio n. 15
0
int
minor_init(void)
{
	devfsadm_print(debug_mid, "usb_link: minor_init\n");
	return (DEVFSADM_SUCCESS);
}
Esempio n. 16
0
/*
 * Determine which port monitor entries already exist by invoking pmadm(1m)
 * to list all configured 'ttymon' port monitor entries.
 * Do not explicitly report errors from executing pmadm(1m) or sacadm(1m)
 * commands to remain compatible with the ports(1m) implementation.
 */
static int
load_ttymondb(void)
{
	char	cmdline[CMDLEN];
	char	cmdbuf[PMTAB_MAXLINE+1];
	int	sac_exitval;
	FILE	*fs_popen;
	char	*portname;	/* pointer to a tty name */
	int	portnum;
	char	*ptr;
	char	*error_msg = "%s: failed to load port monitor database\n";

	(void) strcpy(cmdline, "/usr/sbin/pmadm -L -t ttymon");
	fs_popen = popen(cmdline, "r");
	if (fs_popen == NULL) {
		devfsadm_print(VERBOSE_MID, error_msg, modname);
		return (DEVFSADM_FAILURE);
	}

	while (fgets(cmdbuf, PMTAB_MAXLINE, fs_popen) != NULL) {
		if ((portname = pmtab_parse_portname(cmdbuf)) == NULL) {
			devfsadm_print(VERBOSE_MID,
			    "load_ttymondb: failed to parse portname\n");
			devfsadm_print(VERBOSE_MID,
			    "load_ttymondb: buffer \"%s\"\n", cmdbuf);
			goto load_failed;
		}

		devfsadm_print(PORT_MID, "%s:load_ttymondb: port %s ",
		    modname, portname);

		/*
		 * skip onboard ports
		 * There is no reliable way to determine if we
		 * should start a port monitor on these lines.
		 */
		if ((portnum = parse_portno(portname)) == -1) {
			devfsadm_print(PORT_MID, "ignored\n");
			continue;
		}

		/*
		 * the first field of the pmadm output is
		 * the port monitor name for this entry
		 */
		if ((ptr = strchr(cmdbuf, PMTAB_SEPR)) == NULL) {
			devfsadm_print(VERBOSE_MID,
			    "load_ttymondb: no portmon tag\n");
			goto load_failed;
		}

		*ptr = MN_NULLCHAR;
		if ((pma[portnum].pm_tag = strdup(cmdbuf)) == NULL) {
			devfsadm_errprint("load_ttymondb: failed strdup\n");
			goto load_failed;
		}
		pma[portnum].flags |= PM_HAS_ENTRY;
		pma[PM_SLOT(portnum)].flags |= HAS_PORT_MON;
		devfsadm_print(PORT_MID, "present\n");
	}
	(void) pclose(fs_popen);
	return (DEVFSADM_SUCCESS);

load_failed:

	/*
	 * failed to load the port monitor database
	 */
	devfsadm_print(VERBOSE_MID, error_msg, modname);
	sac_exitval = SAC_EXITVAL(pclose(fs_popen));
	if (sac_exitval != 0) {
		devfsadm_print(VERBOSE_MID,
		    "pmadm: (%s) %s\n", SAC_EID(sac_exitval),
		    SAC_EMSG(sac_exitval));
	}
	return (DEVFSADM_FAILURE);
}