--- old/usr/src/uts/sun4u/montecarlo/io/ttymux_dacf/ttymux_dacf.c	Fri Aug  9 07:21:06 2019
+++ /dev/null	Fri Aug  9 00:52:51 2019
@@ -1,930 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This is a dacf module based upon the Extensions to Device Autoconfiguration
- * project.  See PSARC/1998/212 for more details.
- *
- * This module provides the dacf functions
- * to be called after a driver has attached and before it detaches.
- * The post attach functionality is used to autoconfigure a serial console
- * multiplexer if the OBP console is a multiplexer.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/cmn_err.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/systm.h>
-#include <sys/file.h>
-#include <sys/klwp.h>
-#include <sys/stropts.h>
-#include <sys/stream.h>
-#include <sys/strsubr.h>
-
-#include <sys/consdev.h>
-#include <sys/kbio.h>
-#include <sys/debug.h>
-#include <sys/reboot.h>
-#include <sys/termios.h>
-#include <sys/clock.h>
-
-#include <sys/kstr.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/modctl.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/ndi_impldefs.h>
-
-#include <sys/errno.h>
-#include <sys/devops.h>
-#include <sys/note.h>
-#include <sys/open.h>
-#include <sys/kmem.h>
-#include <sys/dacf.h>
-#include <sys/promif.h>
-
-#include "ttymux_dacf.h"
-
-#pragma weak	find_platform_consoles
-extern char *find_platform_consoles(sm_mux_state_t *_m, dev_info_t *_di,
-    dev_t _d, uint_t _f);
-
-#define	platform_consoles(_m, _di, _d, _f)		\
-	(find_platform_consoles != NULL		\
-	? find_platform_consoles(_m, _di, _d, _f)	\
-	: (nulldev(_m, _di, _d, _f), (char *)0))
-
-/*
- * External functions
- */
-extern uintptr_t space_fetch(char *key);
-extern int space_store(char *key, uintptr_t ptr);
-extern void ttymux_dprintf(int l, const char *fmt, ...);
-extern int prom_ihandle_to_path(ihandle_t, char *, uint_t);
-extern void prom_interpret(char *, uintptr_t, uintptr_t, uintptr_t,
-    uintptr_t, uintptr_t);
-extern ihandle_t prom_stdin_ihandle();
-extern ihandle_t prom_stdout_ihandle();
-
-extern vnode_t *rconsvp;	/* redirection device */
-
-/*
- * Dacf entry points
- */
-static int ttymux_config(dacf_infohdl_t, dacf_arghdl_t, int);
-
-/*
- * Internal functions
- */
-static dacf_op_t ttymuxconfig_op[] = {
-	{ DACF_OPID_POSTATTACH, ttymux_config },
-	{ DACF_OPID_END,	NULL },
-};
-
-static dacf_opset_t opsets[] = {
-	{ "ttymux_config",	ttymuxconfig_op },
-	{ NULL,		NULL }
-};
-
-struct dacfsw dacfsw = {
-	DACF_MODREV_1,
-	opsets,
-};
-
-struct modldacf modldacf = {
-	&mod_dacfops,   /* Type of module */
-	"ttymux DACF",
-	&dacfsw
-};
-
-struct modlinkage modlinkage = {
-	MODREV_1, (void *)&modldacf, NULL
-};
-
-/*LINTLIBRARY*/
-
-/*
- * The following minor nodes can be linked underneath the serial
- * console multiplexer.
- * These are the only ones currently tested.
- * (NOTE: Devices of device_type serial are also allowed to be used as
- * additional consoles).
- * Disallow plumbing of untested node types.
- */
-static const char * const supported_types[] = {
-	DDI_NT_SERIAL, (char *const)NULL
-};
-
-#define	OFLAGS	FREAD|FWRITE|FNOCTTY|FNONBLOCK
-
-#define	INPUT_ALIAS	"multiplexer-input-devices"
-#define	OUTPUT_ALIAS	"multiplexer-output-devices"
-#define	OBPDEV		0x100
-#define	FORTH_STRINGLEN	1024
-#define	MUXDEVTYPE	"SUNW,serial-multiplexer"
-
-static char fth_fmt[] =
-"\" get-device-list\" "	/* ( method-str method-len ) */
-"h# %p "		/* ( method-str method-len ihandle ) */
-"$call-method "		/* ( ihandle_n-1 ... ihandle n ) */
-"dup "			/* ( ihandle_n-1 ... ihandle n n ) */
-"h# %p "		/* ( ihandle_n-1 ... ihandle n n numfound ) */
-"l! "			/* ( ihandle_n-1 ... ihandle n ) */
-"0 "			/* ( ihandle_n-1 ... ihandle n 0 ) */
-"do "			/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i ) */
-"  i "			/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i index ) */
-"  h# %x "		/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i index max) */
-"  < if "		/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i ) */
-"    h# %p "		/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i buf ) */
-"    i "		/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i buf index) */
-"    4 * + "		/* ( ihandle_n-1 ... ihandle_i+1 ihandle_i buf' ) */
-"    l! "		/* ( ihandle_n-1 ... ihandle_i+1 ) */
-"  else "		/* */
-"    drop "		/* ( ihandle_n-1 ... ihandle_i+1 ) */
-"  then "		/* */
-"loop ";		/* ( ihandle_n-1 ... ihandle_i+1 ) */
-
-int
-_init(void)
-{
-	return (mod_install(&modlinkage));
-}
-
-int
-_fini()
-{
-	return (mod_remove(&modlinkage));
-}
-
-int
-_info(struct modinfo *modinfop)
-{
-	return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-ioctl_cmd(vnode_t *avp, int cmd, void *data, int datasize, int *bytecnt)
-{
-	struct strioctl ios;
-	int		rval;
-
-	ios.ic_timout = 0;
-	ios.ic_cmd = cmd;
-	ios.ic_dp = (char *)data;
-	ios.ic_len = datasize;
-
-	rval = kstr_ioctl(avp, I_STR, (intptr_t)&ios);
-	if (bytecnt)
-		*bytecnt = ios.ic_len;
-	return (rval);
-}
-
-/*
- * How many consoles are actually linked underneath the Solaris console
- * multiplexer.
- */
-static int
-usable_consoles(sm_mux_state_t *sp, uint_t *iconsoles, uint_t *oconsoles)
-{
-	uint_t  j, cnt, icnt = 0u, ocnt = 0u;
-
-	mutex_enter(&sp->sm_cons_mutex);
-	for (j = 0, cnt = 0; j < sp->sm_cons_cnt; j++)
-		if (sp->sm_cons_links[j].sm_muxid != 0) {
-			sm_console_t *cn = &sp->sm_cons_links[j];
-			if (cn->sm_mode & FORINPUT)
-				icnt += 1;
-			if (cn->sm_mode & FOROUTPUT)
-				ocnt += 1;
-			if (cn->sm_mode == FORIO)
-				cnt += 1;
-		}
-	mutex_exit(&sp->sm_cons_mutex);
-	*iconsoles = icnt;
-	*oconsoles = ocnt;
-	return (cnt);
-}
-
-/*
- * Before linking a device underneath a serial multiplexer check that
- * its minor node type is supported.
- */
-static boolean_t
-compatible_console(dev_t dev)
-{
-	int			circ;
-	boolean_t		compatible;
-	char *const		*nodetype;
-	struct ddi_minor_data	*dmdp;
-	dev_info_t		*dip;
-	char			devtype[32];
-	int			len;
-
-	/*
-	 * Find the node nodetype to verify that the current version of
-	 * the code supports its use as a console
-	 * Supported types are listed in the array supported_types
-	 */
-	if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL) {
-		ttymux_dprintf(DPRINT_L2, "No dip for %d:%d\n",
-		    getmajor(dev), getminor(dev));
-		return (B_FALSE);
-	}
-
-	compatible = B_FALSE;
-	len = sizeof (devtype);
-
-	ndi_devi_enter(dip, &circ);
-	for (dmdp = DEVI(dip)->devi_minor; dmdp != NULL; dmdp = dmdp->next) {
-		struct ddi_minor_data   *mdp = dmdp;
-
-		if (mdp->ddm_dev == dev) {
-
-			ttymux_dprintf(DPRINT_L0, "compat: matched dev\n");
-			/*
-			 * check the OBP device_type property first
-			 * its a good bet that it will be compatible
-			 * if it has the value serial.
-			 */
-			if (ddi_prop_op(DDI_DEV_T_ANY, dip,
-			    PROP_LEN_AND_VAL_BUF, 0, "device_type",
-			    (caddr_t)devtype, &len) == DDI_PROP_SUCCESS &&
-			    strcmp(devtype, "serial") == 0) {
-				compatible = B_TRUE;
-			} else {
-				for (nodetype =
-				    (char *const *)&supported_types[0];
-				    *nodetype != (char *const)NULL;
-				    nodetype++) {
-					if (strcmp(*nodetype,
-					    mdp->ddm_node_type) == 0) {
-						compatible = B_TRUE;
-						break;
-					}
-				}
-			}
-			break;
-		}
-	}
-	ndi_devi_exit(dip, circ);
-	ddi_release_devi(dip);
-
-	/*
-	 * The current version of the implementation has only been tested
-	 * with a serial multiplexer.
-	 */
-
-	ttymux_dprintf(DPRINT_L0, "%d:%d is %s\n", getmajor(dev),
-	    getminor(dev), (compatible) ? "compatible" : "incompatible");
-
-	return (compatible);
-}
-
-/*
- * get-device-list ( -- [ihandle n-1, ... ihandle], n )
- * Call the "get-device-list" method of an OBP device.
- * ihdl		- ihandle of the OBP device whose method is to be called
- * ihdls	- array of ihandles returned to the caller
- * maxi		- length of the ihdls array
- */
-static int
-get_device_list(ihandle_t ihdl, ihandle_t *ihdls, size_t maxi)
-{
-	int	numfound = -1;
-	char	fstr[FORTH_STRINGLEN];
-
-	if (snprintf(fstr, FORTH_STRINGLEN, fth_fmt, (caddr32_t)ihdl,
-	    &numfound, maxi, ihdls) > FORTH_STRINGLEN) {
-		ttymux_dprintf(DPRINT_L3,
-		    "WARNING: forth buffer size is too small.\n");
-		return (0);
-	}
-
-	prom_interpret(fstr, 0, 0, 0, 0, 0);
-
-	ttymux_dprintf(DPRINT_L0, "ihdl 0x%p cnt %d\n",
-	    (caddr32_t)ihdl, numfound);
-
-	return (numfound);
-}
-
-/*
- * Read an OBP property and return the result in propval.
- * The caller is responsible for freeing the memory.
- */
-static int
-read_prop(pnode_t node, char *propname, char **propval)
-{
-	int	proplen = -1;
-
-	if (node == OBP_BADNODE ||
-	    (proplen = prom_getproplen(node, propname)) <= 0)
-		return (proplen);
-
-	*propval = kmem_zalloc(proplen + 1, KM_SLEEP);
-	(void) prom_getprop(node, propname, *propval);
-
-	return (proplen);
-}
-
-/*
- * Parse a white space separated list of tokens and call
- * the input action with each parsed token.
- */
-static void
-parse(sm_mux_state_t *ms, char *p,
-    void (*action)(sm_mux_state_t *, char *, void *), void *arg)
-{
-	char    *e, *tok = NULL;
-
-	if (p == 0 || *p == 0)
-		return;
-
-	e = p + strlen(p);
-
-	do {
-		switch (*p) {
-		case ' ':
-		case '\t':
-			if (tok != NULL) {
-				*p = 0;
-				action(ms, tok, arg);
-				tok = NULL;
-				*p = ' ';
-			}
-			break;
-		default:
-			if (tok == NULL) {
-				tok = p;
-			}
-			break;
-		}
-	} while (++p < e);
-
-	if (tok != NULL)
-		action(ms, tok, arg);
-}
-
-/*
- * Search for a console structure matching a device path.
- * Return a new initialized structure if one does not exist.
- */
-sm_console_t *
-get_aconsole(sm_mux_state_t *ms, char *path)
-{
-	sm_console_t	*cn;
-	int		j;
-
-	for (cn = ms->sm_cons_links, j = 0;
-	    j < ms->sm_cons_cnt; cn++, j++) {
-		if (cn->sm_path && strcmp(cn->sm_path, path) == 0)
-			break;
-	}
-	if (j == ms->sm_cons_cnt) {
-		if (j + 1 == TTYMUX_MAX_LINKS) {
-			cn = NULL;
-		} else {
-			bzero((caddr_t)cn, sizeof (*cn));
-			ms->sm_cons_cnt += 1;
-		}
-	}
-	return (cn);
-}
-
-/*
- * Create a new console structure representing the device
- * identified by path. The void * argument indicates which I/O
- * mode the device will support.
- */
-static void
-add_aconsole(sm_mux_state_t *ms, char *path, void *arg)
-{
-	sm_console_t	*cn;
-	char		*cpath;
-
-	if (*path == '/') {
-		cpath = kmem_alloc(strlen(path) + 1, KM_SLEEP);
-		(void) strcpy(cpath, path);
-	} else if (read_prop(prom_alias_node(), path, &cpath) <= 0) {
-			return;
-	}
-
-	/*
-	 * Device paths should have a minor name - if its missing assume
-	 * it should be :a!
-	 */
-	if (strrchr(cpath, ':') == NULL) {
-		char	*p;
-		size_t	len = strlen(cpath) + 1;
-
-		p = kmem_zalloc(len + 2, KM_SLEEP);
-		(void) strcpy(p, cpath);
-		(void) strcat(p, ":a");	/* assume :a ! */
-		kmem_free(cpath, len);
-		cpath = p;
-	}
-	if ((cn = get_aconsole(ms, cpath)) != NULL) {
-		cn->sm_obp_con = ((uint_t)(uintptr_t)arg & OBPDEV) ?
-		    B_TRUE : B_FALSE;
-		cn->sm_mode |= (io_mode_t)((uint_t)(uintptr_t)arg & FORIO);
-		if (cn->sm_path != NULL)
-			kmem_free(cn->sm_path, strlen(cn->sm_path) + 1);
-		cn->sm_path = cpath;
-	} else {
-		ttymux_dprintf(DPRINT_L3, "Too many "
-		    " consoles - ignoring %s\n", cpath);
-		kmem_free(cpath, strlen(cpath) + 1);
-	}
-}
-
-/*
- * Discover which consoles OBP is using.
- */
-static int
-find_obp_consoles(sm_mux_state_t *ms, io_mode_t mode)
-{
-	sm_console_t	*cn;
-	int		i, cnt;
-	char		*devpath;
-	ihandle_t	ihdls[TTYMUX_MAX_LINKS];
-	ihandle_t	stdihdl;
-
-	if (mode == FORINPUT)
-		stdihdl = ms->sm_cons_stdin.sm_i_ihdl;
-	else if (mode == FOROUTPUT)
-		stdihdl = ms->sm_cons_stdout.sm_o_ihdl;
-	else
-		return (EINVAL);
-	devpath = kmem_alloc(MAXPATHLEN+2, KM_SLEEP);
-
-	cnt = get_device_list(stdihdl, ihdls, TTYMUX_MAX_LINKS);
-
-	for (i = 0; i < cnt; i++) {
-
-		if (prom_ihandle_to_path(ihdls[i], devpath, MAXPATHLEN) == 0)
-			continue;
-		/*
-		 * If the minor name is not part of the path and there is
-		 * more than one minor node then ddi_pathname_to_dev_t
-		 * can fail to resolve the path correctly (it's an OBP
-		 * problem)!!! If there's no minor name then assume the default
-		 * minor name (:a).
-		 */
-		if (strrchr(devpath, ':') == NULL)
-			(void) strcat(devpath, ":a");	/* assume :a ! */
-
-		if ((cn = get_aconsole(ms, devpath)) == 0) {
-			ttymux_dprintf(DPRINT_L3, "Too many "
-			    " consoles - ignoring %s\n", devpath);
-			continue;
-		}
-
-		cn->sm_mode |= mode;
-		cn->sm_obp_con = B_TRUE;
-		if (mode == FORINPUT)
-			cn->sm_i_ihdl = ihdls[i];
-		else
-			cn->sm_o_ihdl = ihdls[i];
-		if (cn->sm_path == NULL) {
-			cn->sm_path = kmem_alloc(strlen(devpath) + 1, KM_SLEEP);
-			(void) strcpy(cn->sm_path, devpath);
-		}
-
-	}
-	kmem_free(devpath, MAXPATHLEN + 2);
-
-	return (0);
-}
-
-/*
- * Convert a file system path into a dev_t
- */
-static dev_t
-fs_devtype(char *fspath)
-{
-	vnode_t	*vp = NULL;
-	dev_t	dev;
-
-	if (fspath == 0 ||
-	    vn_open(fspath, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0) != 0) {
-		return (NODEV);
-	} else {
-		dev = vp->v_rdev;
-		VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
-		VN_RELE(vp);
-		return (dev);
-	}
-}
-
-/*
- * Convert a device tree path into a dev_t
- */
-static dev_t
-di_devtype(char *path)
-{
-	dev_t   dev;
-
-	if (path == 0 || *path == 0)
-		return (NODEV);
-
-	ttymux_dprintf(DPRINT_L0, "loading device %s\n", path);
-	dev = ddi_pathname_to_dev_t(path);
-
-	return (dev);
-}
-
-
-static int
-open_stream(vnode_t **vp, int *fd, dev_t dev)
-{
-	file_t	*fp;
-	int	rv;
-
-	/* create a vnode for the device and open it */
-	*vp = makespecvp(dev, VCHR);
-	if ((rv = VOP_OPEN(vp, FREAD+FWRITE+FNOCTTY, CRED(), NULL)) != 0) {
-		goto out2;
-	}
-	/* Associate a file pointer with the vnode */
-	if ((rv = falloc(*vp, FREAD+FWRITE+FNOCTTY, &fp, NULL)) != 0) {
-		goto out1;
-	}
-	mutex_exit(&fp->f_tlock);	/* must be called single threaded */
-	/* Allocate a file descriptor (any non-negative integer will suffice) */
-	if ((*fd = ufalloc(0)) == -1) {
-		rv = EMFILE;
-		goto out1;
-	}
-	/* associate the file pointer with the fd */
-	setf(*fd, fp);
-	return (0);
-
-out1:
-	VOP_CLOSE(*vp, FREAD+FWRITE+FNOCTTY, 1, (offset_t)0, CRED(), NULL);
-out2:
-	VN_RELE(*vp);
-	return (rv);
-}
-
-/*
- * Plumb a device specified by the sm_console_t argument underneath the
- * serial multiplexer indicated by the vnode_t argument.
- */
-static int
-link_aconsole(vnode_t *mux_avp, sm_console_t *cn)
-{
-	vnode_t		*lvp;
-	int		lfd;
-	int		rv, rval;
-	ttymux_assoc_t	assoc;
-	struct termios	tc;
-
-	ASSERT(cn->sm_path);
-
-	/* get an open vnode for the device */
-	if ((rv = open_stream(&lvp, &lfd, cn->sm_dev)) != 0)
-		return (rv);
-
-	/*
-	 * Enable the receiver on the lower device since it will
-	 * be used by OBP.
-	 */
-	if ((rv = ioctl_cmd(lvp, TCGETS, &tc, sizeof (tc), 0)) == 0) {
-		tc.c_cflag |= CREAD;
-		rv = ioctl_cmd(lvp, TCSETS, &tc, sizeof (tc), 0);
-	}
-	if (rv != 0)
-		ttymux_dprintf(DPRINT_L3,
-		    "DACF: Failed to enable console receiver [error %d]\n", rv);
-
-	/*
-	 * Pop all the modules off the stream prior to linking it.
-	 */
-	do {
-		rv = strioctl(lvp, I_POP, 0, 0, K_TO_K, CRED(), &rval);
-	} while (rv == 0);
-
-	if (rv != EINVAL) {
-		ttymux_dprintf(DPRINT_L3,
-		    "Failed to pop all modules: error %d", rv);
-		goto out;
-	}
-
-	if ((rv = strioctl(mux_avp, I_PLINK, (intptr_t)lfd,
-	    FREAD+FWRITE+FNOCTTY, K_TO_K, CRED(), &(cn->sm_muxid))) != 0) {
-
-		ttymux_dprintf(DPRINT_L3,
-		    "Failed to link device: error %d", rv);
-		goto out;
-	}
-	/* close the linked device */
-	(void) closeandsetf(lfd, NULL);
-	/*
-	 * Now tell the mux to associate the new stream
-	 */
-	assoc.ttymux_udev = mux_avp->v_rdev;
-	assoc.ttymux_ldev = cn->sm_dev;
-	assoc.ttymux_linkid = cn->sm_muxid;
-	assoc.ttymux_tag = 0;
-	assoc.ttymux_ioflag = cn->sm_mode;
-	if ((rv = ioctl_cmd(mux_avp, TTYMUX_ASSOC,
-	    (void *)&assoc, sizeof (assoc), 0)) != 0) {
-		ttymux_dprintf(DPRINT_L3,
-		    "Failed to associate %d:%d with the console\n",
-		    getmajor(cn->sm_dev), getminor(cn->sm_dev));
-
-		if (strioctl(mux_avp, I_PUNLINK, (intptr_t)cn->sm_muxid, 0,
-		    K_TO_K, CRED(), &rval) != 0)
-			ttymux_dprintf(DPRINT_L3,
-			    "Can't unlink %d:%d - Closing vnode\n",
-			    getmajor(cn->sm_dev), getminor(cn->sm_dev));
-
-	}
-	return (rv);
-
-out:
-	VOP_CLOSE(lvp, FREAD+FWRITE+FNOCTTY, 1, (offset_t)0, CRED(), NULL);
-	VN_RELE(lvp);
-	return (rv);
-}
-
-static int
-enable_aconsole(sm_mux_state_t *ms, sm_console_t *cn, vnode_t *muxvp)
-{
-	ttymux_assoc_t	assoc;
-
-	ASSERT(cn && cn->sm_dev != NODEV);
-
-	assoc.ttymux_ldev = cn->sm_dev;
-
-	cn->sm_muxid = (ioctl_cmd(muxvp, TTYMUX_GETLINK,
-	    (void *)&assoc, sizeof (assoc), 0) == 0) ? assoc.ttymux_linkid : 0;
-
-	if (cn->sm_muxid != 0)
-		return (0);	/* already linked */
-	else
-		return (link_aconsole(muxvp, cn));
-}
-
-/*
- * Enable all discovered consoles such that they can provide real I/O.
- * The discovered list is stored in the sm_mux_state_t pointer.
- */
-static int
-enable_all_consoles(sm_mux_state_t *ms, vnode_t *muxvp)
-{
-	sm_console_t	*cn;
-	uint_t		j;
-
-	ttymux_dprintf(DPRINT_L0, "Enable %d devices\n", ms->sm_cons_cnt);
-	for (cn = ms->sm_cons_links, j = 0;
-	    j < ms->sm_cons_cnt; cn++, j++) {
-
-		if (cn->sm_path == NULL)
-			continue;
-
-		if ((strstr(cn->sm_path, "/dev") == cn->sm_path &&
-		    (cn->sm_dev = fs_devtype(cn->sm_path)) == NODEV) ||
-		    (cn->sm_dev = di_devtype(cn->sm_path)) == NODEV) {
-
-			ttymux_dprintf(DPRINT_L0,
-			    "Cannot find a driver for device: %s\n",
-			    cn->sm_path ? cn->sm_path : "");
-			continue;
-		}
-		ttymux_dprintf(DPRINT_L0, "Enabling %d:%d\n",
-		    getmajor(cn->sm_dev), getminor(cn->sm_dev));
-
-		/*
-		 * Refuse requests to use devices as consoles which have an
-		 * unsupported minor node type.
-		 */
-		if (compatible_console(cn->sm_dev) == B_FALSE)
-			continue;
-
-		/*
-		 * Enable a console device by linking the target console
-		 * underneath the ttymux minor node that has been specified
-		 * in a DACF reservation (see /etc/dacf.conf).
-		 */
-		(void) enable_aconsole(ms, cn, muxvp);
-	}
-	return (0);
-}
-
-static int
-find_consoles(sm_mux_state_t *ms, dev_info_t *dip, dev_t dev)
-{
-	int	len;
-	char	*propval;
-	char	devtype[32];
-	pnode_t	node;
-	uint_t	flags;
-
-	/*
-	 * Look for target consoles based on options node properties
-	 */
-	node = prom_optionsnode();
-	if ((len = read_prop(node, INPUT_ALIAS, &propval)) > 0) {
-		parse(ms, propval, add_aconsole, (void *)FORINPUT);
-		kmem_free(propval, len + 1);
-	}
-	if ((len = read_prop(node, OUTPUT_ALIAS, &propval)) > 0) {
-		parse(ms, propval, add_aconsole, (void *)FOROUTPUT);
-		kmem_free(propval, len + 1);
-	}
-
-	/*
-	 * Look for platform specific target consoles.
-	 * Assume that they are OBP consoles and used for both input and output.
-	 */
-	flags = (uint_t)FORIO | OBPDEV;
-	if ((propval = platform_consoles(ms, dip, dev, flags)) != NULL) {
-		parse(ms, propval, add_aconsole, (void *)(uintptr_t)flags);
-		kmem_free(propval, strlen(propval) + 1);
-	}
-
-	/*
-	 * Discover which consoles OBP is actually using according to
-	 * interfaces proposed by case number FWARC/262.
-	 */
-	len = sizeof (devtype);
-	if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF, 0,
-	    "device_type", (caddr_t)devtype, &len) == DDI_PROP_SUCCESS &&
-	    strcmp(devtype, "serial") == 0 &&
-	    ddi_prop_exists(DDI_DEV_T_ANY, dip, 0, MUXDEVTYPE) == 1) {
-
-		(void) find_obp_consoles(ms, FORINPUT);
-		(void) find_obp_consoles(ms, FOROUTPUT);
-
-	}
-	ttymux_dprintf(DPRINT_L0, "%d consoles configured\n",
-	    ms->sm_cons_cnt);
-	return (ms->sm_cons_cnt);
-}
-
-static int
-validate_reservation(dacf_infohdl_t di, dev_info_t **dip, dev_t *dev,
-    io_mode_t *mode)
-{
-	char	*dname, *nname, *ipath, *opath;
-
-	if ((dname = (char *)dacf_driver_name(di)) == NULL)
-		return (EINVAL);
-
-	if ((*dip = dacf_devinfo_node(di)) == NULL)
-		return (EINVAL);
-
-	*dev = makedevice(ddi_driver_major(*dip), dacf_minor_number(di));
-
-	if (*dev == NODEV || *dip == NULL || strcmp(dname, TTYMUX_DRVNAME) != 0)
-		return (EINVAL);
-	else if (getminor(*dev) != (minor_t)0)
-		return (EINVAL);	/* minor 0 is special */
-	else if (rconsvp != NULL || space_fetch(TTYMUXPTR) != NULL)
-		return (EAGAIN);	/* already configured */
-
-	opath = prom_stdoutpath();
-	ipath = prom_stdinpath();
-	nname = ddi_node_name(*dip);
-	*mode = 0;
-
-	if (ipath != NULL && strstr(ipath, nname) != 0)
-		*mode = FORINPUT;
-	if (opath != NULL && strstr(opath, nname) != 0)
-		*mode |= FOROUTPUT;
-	if ((*mode & FORIO) == 0)
-		return (EINVAL);
-	if ((*mode & FOROUTPUT) == 0) {
-		ttymux_dprintf(DPRINT_L3,
-		    "Warning: multiplexer is not the output device\n");
-	}
-	if ((*mode & FORINPUT) == 0) {
-		ttymux_dprintf(DPRINT_L3,
-		    "Warning: multiplexer is not the input device\n");
-	}
-	return (0);
-}
-
-/*
- * This operation set is for configuring the ttymux driver for use as
- * the system console.
- * It must run before consconfig configures the Solaris console.
- */
-/*ARGSUSED*/
-static int
-ttymux_config(dacf_infohdl_t info_hdl, dacf_arghdl_t arg_hdl, int flags)
-{
-	sm_mux_state_t	*ms;
-	io_mode_t	mode;
-	dev_t		dev;
-	dev_info_t	*dip;
-	uint_t		i, icnt = 0, ocnt = 0;
-	int		rv;
-	vnode_t		*muxvp;
-
-	ttymux_dprintf(DPRINT_L0, "\n");
-
-	if ((rv = validate_reservation(info_hdl, &dip, &dev, &mode)) != 0) {
-		ttymux_dprintf(DPRINT_L0, "reservation ignored (%d)\n", rv);
-		return (DACF_SUCCESS);
-	}
-
-	ms = kmem_zalloc(sizeof (*ms), KM_SLEEP);
-
-	mutex_init(&ms->sm_cons_mutex, NULL, MUTEX_DRIVER, NULL);
-
-	for (i = 0; i < TTYMUX_MAX_LINKS; i++)
-		ms->sm_cons_links[i].sm_dev = NODEV;
-
-	ms->sm_cons_stdin.sm_dev = ms->sm_cons_stdout.sm_dev = NODEV;
-	if (mode & FORINPUT)
-		ms->sm_cons_stdin.sm_dev = dev;
-	if (mode & FOROUTPUT)
-		ms->sm_cons_stdout.sm_dev = dev;
-	ms->sm_cons_stdin.sm_i_ihdl = prom_stdin_ihandle();
-	ms->sm_cons_stdout.sm_o_ihdl = prom_stdout_ihandle();
-
-	if (prom_is_openprom()) {
-		pnode_t	node = prom_optionsnode();
-
-		if (prom_getproplen(node, INPUT_ALIAS) > 0) {
-			ms->sm_ialias = kmem_alloc(
-			    strlen(INPUT_ALIAS) + 1, KM_SLEEP);
-			(void) strcpy(ms->sm_ialias, INPUT_ALIAS);
-		}
-		if (prom_getproplen(node, OUTPUT_ALIAS) > 0) {
-			ms->sm_oalias = kmem_alloc(
-			    strlen(OUTPUT_ALIAS) + 1, KM_SLEEP);
-			(void) strcpy(ms->sm_oalias, OUTPUT_ALIAS);
-		}
-	}
-
-	(void) find_consoles(ms, dip, dev);
-	/* Store the console list for use by the ttymux driver */
-	if (space_store(TTYMUXPTR, (uintptr_t)ms) != 0) {
-		ttymux_dprintf(DPRINT_L3, "Named pointer error\n");
-		if (ms->sm_ialias)
-			kmem_free(ms->sm_ialias, strlen(ms->sm_ialias) + 1);
-		if (ms->sm_oalias)
-			kmem_free(ms->sm_oalias, strlen(ms->sm_oalias) + 1);
-		for (i = 0; i < ms->sm_cons_cnt; i++) {
-			sm_console_t *cn = &ms->sm_cons_links[i];
-			if (cn->sm_path)
-				kmem_free(cn->sm_path, strlen(cn->sm_path) + 1);
-		}
-		kmem_free(ms, sizeof (*ms));
-		return (DACF_FAILURE);
-	}
-
-	muxvp = dacf_makevp(info_hdl);
-
-	if ((rv = VOP_OPEN(&muxvp, OFLAGS, CRED(), NULL)) == 0) {
-
-		(void) enable_all_consoles(ms, muxvp);
-		(void) usable_consoles(ms, &icnt, &ocnt);
-
-		VOP_CLOSE(muxvp, OFLAGS, 1, (offset_t)0, CRED(), NULL);
-		VN_RELE(muxvp);
-	} else {
-		ttymux_dprintf(DPRINT_L3,
-		    "Error %d opening the console device\n", rv);
-		VN_RELE(muxvp);
-		return (DACF_FAILURE);
-	}
-
-	if (icnt == 0 && (mode & FORINPUT))
-		ttymux_dprintf(DPRINT_L3, "No input consoles configured.\n");
-	if (ocnt == 0 && (mode & FOROUTPUT))
-		ttymux_dprintf(DPRINT_L3, "No output consoles configured.\n");
-
-	ttymux_dprintf(DPRINT_L0, "mux config complete\n");
-
-	return (DACF_SUCCESS);
-}
