Пример #1
0
/*
 * 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);
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
/*
 * 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);
}
Пример #5
0
/*
 * port monitor array mgmt
 */
static void *
pma_alloc(void)
{

	if (pma != NULL) {
		devfsadm_errprint("%s:pma_alloc:pma != NULL\n", modname);
		return (NULL);
	}

	if ((pma = calloc(maxports + 1, sizeof (*pma))) == NULL) {
		devfsadm_errprint("%s:pma_alloc:pma alloc failure\n", modname);
		return (NULL);
	}

	return ((void *)pma);
}
Пример #6
0
/*
 * 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);
}
Пример #7
0
static int
disk_callback_fabric(di_minor_t minor, di_node_t node)
{
	char disk[DISK_SUBPATH_MAX];
	int lun;
	int count;
	int *intp;
	uchar_t *str;
	uchar_t *wwn;
	uchar_t ascii_wwn[ASCIIWWNSIZE];

	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
	    "client-guid", (char **)&wwn) > 0) {
		if (strlcpy((char *)ascii_wwn, (char *)wwn,
		    sizeof (ascii_wwn)) >= sizeof (ascii_wwn)) {
			devfsadm_errprint("SUNW_disk_link: GUID too long:%d",
			    strlen((char *)wwn));
			return (DEVFSADM_CONTINUE);
		}
		lun = 0;
	} else if (di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
	    "port-wwn", &wwn) > 0) {
		if (di_prop_lookup_ints(DDI_DEV_T_ANY, node,
		    SCSI_ADDR_PROP_LUN, &intp) > 0) {
			lun = *intp;
		} else {
			lun = 0;
		}

		for (count = 0, str = ascii_wwn; count < 8; count++, str += 2) {
			(void) sprintf((caddr_t)str, "%02x", wwn[count]);
		}
		*str = '\0';
	} else {
		return (DEVFSADM_CONTINUE);
	}

	for (str = ascii_wwn; *str != '\0'; str++) {
		*str = DISK_LINK_TO_UPPER(*str);
	}

	(void) snprintf(disk, DISK_SUBPATH_MAX, "t%sd%d", ascii_wwn, lun);

	disk_common(minor, node, disk, RM_STALE);

	return (DEVFSADM_CONTINUE);
}
Пример #8
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);
}
Пример #9
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);
}
Пример #10
0
/*
 * Called for all serial devices that are NOT onboard
 * Creates links of the form "/dev/term/[0..n]"
 * Schedules an update the sacadm (portmon).
 */
static int
serial_port_create(di_minor_t minor, di_node_t node)
{
	char l_path[MAXPATHLEN], p_path[MAXPATHLEN];
	char *devfspath, *buf, *minor_name;
	int port_num;

	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);
	}

	/*
	 * verify dialout ports do not come in on this nodetype
	 */
	if (is_dialout(minor_name)) {
		devfsadm_errprint("%s: dialout device\n\t%s:%s\n",
		    modname, devfspath, minor_name);
		di_devfs_path_free(devfspath);
		return (DEVFSADM_CONTINUE);
	}

	/*
	 *  add the minor name to the physical path so we can
	 *  enum the port# and create the the link.
	 */
	(void) strcpy(p_path, devfspath);
	(void) strcat(p_path, ":");
	(void) strcat(p_path, minor_name);
	di_devfs_path_free(devfspath);

	if (devfsadm_enumerate_int(p_path, 0, &buf, port_rules, 1)) {
		devfsadm_errprint("%s:serial_port_create:"
		    " enumerate_int() failed\n\t%s\n",
		    modname, p_path);
		return (DEVFSADM_CONTINUE);
	}

	(void) strcpy(l_path, "term/");
	(void) strcat(l_path, buf);
	(void) devfsadm_mklink(l_path, node, minor, 0);

	/*
	 * update the portmon database if this port falls within
	 * the valid range of ports.
	 */
	if ((port_num = parse_portno(buf)) != -1) {
		pma[port_num].flags |= HAS_PORT_DEVICE;
	}

	free(buf);
	return (DEVFSADM_CONTINUE);
}