xref: /illumos-gate/usr/src/uts/common/io/vcons.c (revision 5c22bad5)
1aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2aecfc01dSrui zang - Sun Microsystems - Beijing China  * CDDL HEADER START
3aecfc01dSrui zang - Sun Microsystems - Beijing China  *
4aecfc01dSrui zang - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
5aecfc01dSrui zang - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
6aecfc01dSrui zang - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
7aecfc01dSrui zang - Sun Microsystems - Beijing China  *
8aecfc01dSrui zang - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9aecfc01dSrui zang - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
10aecfc01dSrui zang - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
11aecfc01dSrui zang - Sun Microsystems - Beijing China  * and limitations under the License.
12aecfc01dSrui zang - Sun Microsystems - Beijing China  *
13aecfc01dSrui zang - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
14aecfc01dSrui zang - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15aecfc01dSrui zang - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
16aecfc01dSrui zang - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
17aecfc01dSrui zang - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
18aecfc01dSrui zang - Sun Microsystems - Beijing China  *
19aecfc01dSrui zang - Sun Microsystems - Beijing China  * CDDL HEADER END
20aecfc01dSrui zang - Sun Microsystems - Beijing China  */
21aecfc01dSrui zang - Sun Microsystems - Beijing China 
22aecfc01dSrui zang - Sun Microsystems - Beijing China /*
23ceeba6f9Srui zang - Sun Microsystems - Beijing China  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24aecfc01dSrui zang - Sun Microsystems - Beijing China  */
25aecfc01dSrui zang - Sun Microsystems - Beijing China 
26aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/types.h>
27aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/param.h>
28aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/signal.h>
29aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/cred.h>
30aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vnode.h>
31aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/termios.h>
32aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/termio.h>
33aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/ttold.h>
34aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/stropts.h>
35aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/stream.h>
36aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/strsun.h>
37aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/tty.h>
38aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/buf.h>
39aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/uio.h>
40aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/stat.h>
41aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sysmacros.h>
42aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/errno.h>
43aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/proc.h>
44aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/procset.h>
45aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/fault.h>
46aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/siginfo.h>
47aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/debug.h>
48aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/kd.h>
49aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vt.h>
50aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vtdaemon.h>
51aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/session.h>
52aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/door.h>
53aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/kmem.h>
54aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/cpuvar.h>
55aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/kbio.h>
56aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/strredir.h>
57aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/fs/snode.h>
58aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/consdev.h>
59aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/conf.h>
60aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/cmn_err.h>
61aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/console.h>
62aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/promif.h>
63aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/note.h>
64aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/polled_io.h>
65aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/systm.h>
66aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/ddi.h>
67aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sunddi.h>
68aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sunndi.h>
69aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/esunddi.h>
70aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/sunldi.h>
71aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/debug.h>
72aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/console.h>
73aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/ddi_impldefs.h>
74aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/policy.h>
75aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/tem.h>
76aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/wscons.h>
77aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/systm.h>
78aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/modctl.h>
79aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/vt_impl.h>
80aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/consconfig_dacf.h>
81aecfc01dSrui zang - Sun Microsystems - Beijing China 
82aecfc01dSrui zang - Sun Microsystems - Beijing China /*
83aecfc01dSrui zang - Sun Microsystems - Beijing China  * This file belongs to wc STREAMS module which has a D_MTPERMODE
84aecfc01dSrui zang - Sun Microsystems - Beijing China  * inner perimeter. See "Locking Policy" comment in wscons.c for
85aecfc01dSrui zang - Sun Microsystems - Beijing China  * more information.
86aecfc01dSrui zang - Sun Microsystems - Beijing China  */
87aecfc01dSrui zang - Sun Microsystems - Beijing China 
88aecfc01dSrui zang - Sun Microsystems - Beijing China /*
89aecfc01dSrui zang - Sun Microsystems - Beijing China  * Minor	name		device file		Hotkeys
90aecfc01dSrui zang - Sun Microsystems - Beijing China  *
91aecfc01dSrui zang - Sun Microsystems - Beijing China  * 0	the system console	/dev/console		Alt + F1
92aecfc01dSrui zang - Sun Microsystems - Beijing China  * 0:	virtual console #1	/dev/vt/0		Alt + F1
93aecfc01dSrui zang - Sun Microsystems - Beijing China  *
94aecfc01dSrui zang - Sun Microsystems - Beijing China  * 2:   virtual console #2	/dev/vt/2		Alt + F2
95aecfc01dSrui zang - Sun Microsystems - Beijing China  * 3:	virtual console #3	/dev/vt/3		Alt + F3
96aecfc01dSrui zang - Sun Microsystems - Beijing China  * ......
97aecfc01dSrui zang - Sun Microsystems - Beijing China  * n:	virtual console #n	/dev/vt/n		Alt + Fn
98aecfc01dSrui zang - Sun Microsystems - Beijing China  *
99aecfc01dSrui zang - Sun Microsystems - Beijing China  * Note that vtdaemon is running on /dev/vt/1 (minor=1),
100aecfc01dSrui zang - Sun Microsystems - Beijing China  * which is not available to end users.
101aecfc01dSrui zang - Sun Microsystems - Beijing China  *
102aecfc01dSrui zang - Sun Microsystems - Beijing China  */
103aecfc01dSrui zang - Sun Microsystems - Beijing China 
104aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_DAEMON_MINOR	1
105aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_IS_DAEMON(minor)	((minor) == VT_DAEMON_MINOR)
106aecfc01dSrui zang - Sun Microsystems - Beijing China 
107aecfc01dSrui zang - Sun Microsystems - Beijing China extern void	wc_get_size(vc_state_t *pvc);
108aecfc01dSrui zang - Sun Microsystems - Beijing China extern boolean_t consconfig_console_is_tipline(void);
109aecfc01dSrui zang - Sun Microsystems - Beijing China 
110aecfc01dSrui zang - Sun Microsystems - Beijing China 
111aecfc01dSrui zang - Sun Microsystems - Beijing China minor_t vc_last_console = VT_MINOR_INVALID;	/* the last used console */
112aecfc01dSrui zang - Sun Microsystems - Beijing China volatile uint_t	vc_target_console;		/* arg (1..n) */
113aecfc01dSrui zang - Sun Microsystems - Beijing China 
114aecfc01dSrui zang - Sun Microsystems - Beijing China static volatile minor_t vc_inuse_max_minor = 0;
115aecfc01dSrui zang - Sun Microsystems - Beijing China static list_t vc_waitactive_list;
116aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(SCHEME_PROTECTS_DATA("D_MTPERMOD protected data", vc_target_console))
117aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(SCHEME_PROTECTS_DATA("D_MTPERMOD protected data", vc_last_console))
118aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(SCHEME_PROTECTS_DATA("D_MTPERMOD protected data", vc_inuse_max_minor))
119aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(SCHEME_PROTECTS_DATA("D_MTPERMOD protected data", vc_waitactive_list))
120aecfc01dSrui zang - Sun Microsystems - Beijing China 
121aecfc01dSrui zang - Sun Microsystems - Beijing China static int vt_pending_vtno = -1;
122aecfc01dSrui zang - Sun Microsystems - Beijing China kmutex_t vt_pending_vtno_lock;
123aecfc01dSrui zang - Sun Microsystems - Beijing China _NOTE(MUTEX_PROTECTS_DATA(vt_pending_vtno_lock, vt_pending_vtno))
124aecfc01dSrui zang - Sun Microsystems - Beijing China 
125aecfc01dSrui zang - Sun Microsystems - Beijing China static int vt_activate(uint_t vt_no, cred_t *credp);
126aecfc01dSrui zang - Sun Microsystems - Beijing China static void vt_copyout(queue_t *qp, mblk_t *mp, mblk_t *tmp, uint_t size);
127aecfc01dSrui zang - Sun Microsystems - Beijing China static void vt_copyin(queue_t *qp, mblk_t *mp, uint_t size);
128aecfc01dSrui zang - Sun Microsystems - Beijing China static void vt_iocnak(queue_t *qp, mblk_t *mp, int error);
129aecfc01dSrui zang - Sun Microsystems - Beijing China static void vt_iocack(queue_t *qp, mblk_t *mp);
130aecfc01dSrui zang - Sun Microsystems - Beijing China 
131aecfc01dSrui zang - Sun Microsystems - Beijing China static uint_t vt_minor2arg(minor_t minor);
132aecfc01dSrui zang - Sun Microsystems - Beijing China static minor_t vt_arg2minor(uint_t arg);
133aecfc01dSrui zang - Sun Microsystems - Beijing China 
134aecfc01dSrui zang - Sun Microsystems - Beijing China /*
135aecfc01dSrui zang - Sun Microsystems - Beijing China  * If the system console is directed to tipline, consider /dev/vt/0 as
136aecfc01dSrui zang - Sun Microsystems - Beijing China  * not being used.
137aecfc01dSrui zang - Sun Microsystems - Beijing China  * For other VT, if it is opened and tty is initialized, consider it
138aecfc01dSrui zang - Sun Microsystems - Beijing China  * as being used.
139aecfc01dSrui zang - Sun Microsystems - Beijing China  */
140aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_IS_INUSE(id)						\
141aecfc01dSrui zang - Sun Microsystems - Beijing China 	(((vt_minor2vc(id))->vc_flags & WCS_ISOPEN) &&		\
142aecfc01dSrui zang - Sun Microsystems - Beijing China 	((vt_minor2vc(id))->vc_flags & WCS_INIT) &&		\
143aecfc01dSrui zang - Sun Microsystems - Beijing China 	(id != 0 || !consconfig_console_is_tipline()))
144aecfc01dSrui zang - Sun Microsystems - Beijing China 
145aecfc01dSrui zang - Sun Microsystems - Beijing China /*
146aecfc01dSrui zang - Sun Microsystems - Beijing China  * the vt switching message is encoded as:
147aecfc01dSrui zang - Sun Microsystems - Beijing China  *
148aecfc01dSrui zang - Sun Microsystems - Beijing China  *   -------------------------------------------------------------
149aecfc01dSrui zang - Sun Microsystems - Beijing China  *   |  \033  |  'Q'  |  vtno + 'A'  |  opcode  |  'z'  |  '\0'  |
150aecfc01dSrui zang - Sun Microsystems - Beijing China  *   -------------------------------------------------------------
151aecfc01dSrui zang - Sun Microsystems - Beijing China  */
152aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_MSG_SWITCH(mp)					\
153aecfc01dSrui zang - Sun Microsystems - Beijing China 	((int)((mp)->b_wptr - (mp)->b_rptr) >= 5 &&		\
154aecfc01dSrui zang - Sun Microsystems - Beijing China 	*((mp)->b_rptr) == '\033' &&				\
155aecfc01dSrui zang - Sun Microsystems - Beijing China 	*((mp)->b_rptr + 1) == 'Q' &&				\
156aecfc01dSrui zang - Sun Microsystems - Beijing China 	*((mp)->b_rptr + 4) == 'z')
157aecfc01dSrui zang - Sun Microsystems - Beijing China 
158aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_MSG_VTNO(mp)		(*((mp)->b_rptr + 2) - 'A')
159aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_MSG_OPCODE(mp)	(*((mp)->b_rptr + 3))
160aecfc01dSrui zang - Sun Microsystems - Beijing China 
161aecfc01dSrui zang - Sun Microsystems - Beijing China #define	VT_DOORCALL_MAX_RETRY	3
162aecfc01dSrui zang - Sun Microsystems - Beijing China 
163aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_init_ttycommon(tty_common_t * pcommon)164aecfc01dSrui zang - Sun Microsystems - Beijing China vt_init_ttycommon(tty_common_t *pcommon)
165aecfc01dSrui zang - Sun Microsystems - Beijing China {
166aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct termios *termiosp;
167aecfc01dSrui zang - Sun Microsystems - Beijing China 	int len;
168aecfc01dSrui zang - Sun Microsystems - Beijing China 
169aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_init(&pcommon->t_excl, NULL, MUTEX_DEFAULT, NULL);
170aecfc01dSrui zang - Sun Microsystems - Beijing China 	pcommon->t_iflag = 0;
171aecfc01dSrui zang - Sun Microsystems - Beijing China 
172aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
173aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Get the default termios settings (cflag).
174aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * These are stored as a property in the
175aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * "options" node.
176aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
177aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (ddi_getlongprop(DDI_DEV_T_ANY,
178aecfc01dSrui zang - Sun Microsystems - Beijing China 	    ddi_root_node(), 0, "ttymodes",
179aecfc01dSrui zang - Sun Microsystems - Beijing China 	    (caddr_t)&termiosp, &len) == DDI_PROP_SUCCESS) {
180aecfc01dSrui zang - Sun Microsystems - Beijing China 
181aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (len == sizeof (struct termios))
182aecfc01dSrui zang - Sun Microsystems - Beijing China 			pcommon->t_cflag = termiosp->c_cflag;
183aecfc01dSrui zang - Sun Microsystems - Beijing China 		else
184aecfc01dSrui zang - Sun Microsystems - Beijing China 			cmn_err(CE_WARN,
185aecfc01dSrui zang - Sun Microsystems - Beijing China 			    "wc: Couldn't get ttymodes property!");
186aecfc01dSrui zang - Sun Microsystems - Beijing China 
187aecfc01dSrui zang - Sun Microsystems - Beijing China 		kmem_free(termiosp, len);
188aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else {
189aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
190aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Gack!  Whine about it.
191aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
192aecfc01dSrui zang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN,
193aecfc01dSrui zang - Sun Microsystems - Beijing China 		    "wc: Couldn't get ttymodes property!");
194aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
195aecfc01dSrui zang - Sun Microsystems - Beijing China 
196aecfc01dSrui zang - Sun Microsystems - Beijing China 	pcommon->t_iocpending = NULL;
197aecfc01dSrui zang - Sun Microsystems - Beijing China }
198aecfc01dSrui zang - Sun Microsystems - Beijing China 
199aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vt_config(uint_t count)200aecfc01dSrui zang - Sun Microsystems - Beijing China vt_config(uint_t count)
201aecfc01dSrui zang - Sun Microsystems - Beijing China {
202aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (consmode != CONS_KFB)
203aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENOTSUP);
204aecfc01dSrui zang - Sun Microsystems - Beijing China 
205aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* one for system console, one for vtdaemon */
206aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count < 2)
207aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
208aecfc01dSrui zang - Sun Microsystems - Beijing China 
209aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
210aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Shouldn't allow to shrink the max vt minor to be smaller than
211aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * the max in used minor.
212aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
213aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count <= vc_inuse_max_minor)
214aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EBUSY);
215aecfc01dSrui zang - Sun Microsystems - Beijing China 
216aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&vc_lock);
217aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_resize(count);
218aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vc_lock);
219aecfc01dSrui zang - Sun Microsystems - Beijing China 
220aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (0);
221aecfc01dSrui zang - Sun Microsystems - Beijing China }
222aecfc01dSrui zang - Sun Microsystems - Beijing China 
223aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_clean(queue_t * q,vc_state_t * pvc)224aecfc01dSrui zang - Sun Microsystems - Beijing China vt_clean(queue_t *q, vc_state_t *pvc)
225aecfc01dSrui zang - Sun Microsystems - Beijing China {
226aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(MUTEX_HELD(&pvc->vc_state_lock));
227aecfc01dSrui zang - Sun Microsystems - Beijing China 
228aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc->vc_bufcallid != 0) {
229aecfc01dSrui zang - Sun Microsystems - Beijing China 		qunbufcall(q, pvc->vc_bufcallid);
230aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_bufcallid = 0;
231aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
232aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc->vc_timeoutid != 0) {
233aecfc01dSrui zang - Sun Microsystems - Beijing China 		(void) quntimeout(q, pvc->vc_timeoutid);
234aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_timeoutid = 0;
235aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
236aecfc01dSrui zang - Sun Microsystems - Beijing China 	ttycommon_close(&pvc->vc_ttycommon);
237aecfc01dSrui zang - Sun Microsystems - Beijing China 
238aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_flags &= ~WCS_INIT;
239aecfc01dSrui zang - Sun Microsystems - Beijing China }
240aecfc01dSrui zang - Sun Microsystems - Beijing China 
241aecfc01dSrui zang - Sun Microsystems - Beijing China /*
242aecfc01dSrui zang - Sun Microsystems - Beijing China  * Reply the VT_WAITACTIVE ioctl.
243aecfc01dSrui zang - Sun Microsystems - Beijing China  * Argument 'close' usage:
244aecfc01dSrui zang - Sun Microsystems - Beijing China  * B_TRUE:  the vt designated by argument 'minor' is being closed.
245aecfc01dSrui zang - Sun Microsystems - Beijing China  * B_FALSE: the vt designated by argument 'minor' has been activated just now.
246aecfc01dSrui zang - Sun Microsystems - Beijing China  */
247aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vc_waitactive_reply(int minor,boolean_t close)248aecfc01dSrui zang - Sun Microsystems - Beijing China vc_waitactive_reply(int minor, boolean_t close)
249aecfc01dSrui zang - Sun Microsystems - Beijing China {
250aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_waitactive_msg_t *index, *tmp;
251aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc;
252aecfc01dSrui zang - Sun Microsystems - Beijing China 
253aecfc01dSrui zang - Sun Microsystems - Beijing China 	index = list_head(&vc_waitactive_list);
254aecfc01dSrui zang - Sun Microsystems - Beijing China 
255aecfc01dSrui zang - Sun Microsystems - Beijing China 	while (index != NULL) {
256aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp = index;
257aecfc01dSrui zang - Sun Microsystems - Beijing China 		index = list_next(&vc_waitactive_list, index);
258aecfc01dSrui zang - Sun Microsystems - Beijing China 
259aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((close && tmp->wa_msg_minor == minor) ||
260aecfc01dSrui zang - Sun Microsystems - Beijing China 		    (!close && tmp->wa_wait_minor == minor)) {
261aecfc01dSrui zang - Sun Microsystems - Beijing China 			list_remove(&vc_waitactive_list, tmp);
262aecfc01dSrui zang - Sun Microsystems - Beijing China 			pvc = vt_minor2vc(tmp->wa_msg_minor);
263aecfc01dSrui zang - Sun Microsystems - Beijing China 
264aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (close)
265aecfc01dSrui zang - Sun Microsystems - Beijing China 				vt_iocnak(pvc->vc_wq, tmp->wa_mp, ENXIO);
266aecfc01dSrui zang - Sun Microsystems - Beijing China 			else
267aecfc01dSrui zang - Sun Microsystems - Beijing China 				vt_iocack(pvc->vc_wq, tmp->wa_mp);
268aecfc01dSrui zang - Sun Microsystems - Beijing China 
269aecfc01dSrui zang - Sun Microsystems - Beijing China 			kmem_free(tmp, sizeof (vc_waitactive_msg_t));
270aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
271aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
272aecfc01dSrui zang - Sun Microsystems - Beijing China }
273aecfc01dSrui zang - Sun Microsystems - Beijing China 
274aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_close(queue_t * q,vc_state_t * pvc,cred_t * credp)275aecfc01dSrui zang - Sun Microsystems - Beijing China vt_close(queue_t *q, vc_state_t *pvc, cred_t *credp)
276aecfc01dSrui zang - Sun Microsystems - Beijing China {
277aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t index;
278aecfc01dSrui zang - Sun Microsystems - Beijing China 
279aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&pvc->vc_state_lock);
280aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_clean(q, pvc);
281aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_flags &= ~WCS_ISOPEN;
282aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&pvc->vc_state_lock);
283aecfc01dSrui zang - Sun Microsystems - Beijing China 
284aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_destroy(pvc->vc_tem, credp);
285aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_tem = NULL;
286aecfc01dSrui zang - Sun Microsystems - Beijing China 
287aecfc01dSrui zang - Sun Microsystems - Beijing China 	index = pvc->vc_minor;
288aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (index == vc_inuse_max_minor) {
289aecfc01dSrui zang - Sun Microsystems - Beijing China 		while ((--index > 0) && !VT_IS_INUSE(index))
290aecfc01dSrui zang - Sun Microsystems - Beijing China 			;
291aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_inuse_max_minor = index;
292aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
293aecfc01dSrui zang - Sun Microsystems - Beijing China 
294aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_waitactive_reply(pvc->vc_minor, B_TRUE);
295aecfc01dSrui zang - Sun Microsystems - Beijing China }
296aecfc01dSrui zang - Sun Microsystems - Beijing China 
297aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_init_tty(vc_state_t * pvc)298aecfc01dSrui zang - Sun Microsystems - Beijing China vt_init_tty(vc_state_t *pvc)
299aecfc01dSrui zang - Sun Microsystems - Beijing China {
300aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(MUTEX_HELD(&pvc->vc_state_lock));
301aecfc01dSrui zang - Sun Microsystems - Beijing China 
302aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_flags |= WCS_INIT;
303aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_init_ttycommon(&pvc->vc_ttycommon);
304aecfc01dSrui zang - Sun Microsystems - Beijing China 	wc_get_size(pvc);
305aecfc01dSrui zang - Sun Microsystems - Beijing China }
306aecfc01dSrui zang - Sun Microsystems - Beijing China 
307aecfc01dSrui zang - Sun Microsystems - Beijing China /*
308aecfc01dSrui zang - Sun Microsystems - Beijing China  * minor 0:	/dev/vt/0	(index = 0, indicating the system console)
309aecfc01dSrui zang - Sun Microsystems - Beijing China  * minor 1:	/dev/vt/1	(index = 1, vtdaemon special console)
310aecfc01dSrui zang - Sun Microsystems - Beijing China  * minor 2:	/dev/vt/2	(index = 2, virtual consoles)
311aecfc01dSrui zang - Sun Microsystems - Beijing China  * ......
312aecfc01dSrui zang - Sun Microsystems - Beijing China  * minor n:	/dev/vt/n	(index = n)
313aecfc01dSrui zang - Sun Microsystems - Beijing China  *
314aecfc01dSrui zang - Sun Microsystems - Beijing China  *
315aecfc01dSrui zang - Sun Microsystems - Beijing China  * The system console (minor 0), is opened firstly and used during console
316aecfc01dSrui zang - Sun Microsystems - Beijing China  * configuration.  It also acts as the system hard console even when all
317aecfc01dSrui zang - Sun Microsystems - Beijing China  * virtual consoles go off.
318aecfc01dSrui zang - Sun Microsystems - Beijing China  *
319aecfc01dSrui zang - Sun Microsystems - Beijing China  * In tipline case, minor 0 (/dev/vt/0) is reserved, and cannot be switched to.
320aecfc01dSrui zang - Sun Microsystems - Beijing China  * And the system console is redirected to the tipline. During normal cases,
321aecfc01dSrui zang - Sun Microsystems - Beijing China  * we can switch from virtual consoles to it by pressing 'Alt + F1'.
322aecfc01dSrui zang - Sun Microsystems - Beijing China  *
323aecfc01dSrui zang - Sun Microsystems - Beijing China  * minor 1 (/dev/vt/1) is reserved for vtdaemon special console, and it's
324aecfc01dSrui zang - Sun Microsystems - Beijing China  * not available to end users.
325aecfc01dSrui zang - Sun Microsystems - Beijing China  *
326aecfc01dSrui zang - Sun Microsystems - Beijing China  * During early console configuration, consconfig_dacf opens wscons and then
327aecfc01dSrui zang - Sun Microsystems - Beijing China  * issue a WC_OPEN_FB ioctl to kick off terminal init process. So during
328aecfc01dSrui zang - Sun Microsystems - Beijing China  * consconfig_dacf first opening of wscons, tems (of type tem_state_t) is
329aecfc01dSrui zang - Sun Microsystems - Beijing China  * not initialized. We do not initialize the tem_vt_state_t instance returned
330aecfc01dSrui zang - Sun Microsystems - Beijing China  * by tem_init() for this open, since we do not have enough info to handle
331aecfc01dSrui zang - Sun Microsystems - Beijing China  * normal terminal operation at this moment. This tem_vt_state_t instance
332aecfc01dSrui zang - Sun Microsystems - Beijing China  * will get initialized when handling WC_OPEN_FB.
333aecfc01dSrui zang - Sun Microsystems - Beijing China  */
334aecfc01dSrui zang - Sun Microsystems - Beijing China int
vt_open(minor_t minor,queue_t * rq,cred_t * crp)335aecfc01dSrui zang - Sun Microsystems - Beijing China vt_open(minor_t minor, queue_t *rq, cred_t *crp)
336aecfc01dSrui zang - Sun Microsystems - Beijing China {
337aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc;
338aecfc01dSrui zang - Sun Microsystems - Beijing China 
339aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!vt_minor_valid(minor))
340aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
341aecfc01dSrui zang - Sun Microsystems - Beijing China 
342aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc = vt_minor2vc(minor);
343aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc == NULL)
344aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
345aecfc01dSrui zang - Sun Microsystems - Beijing China 
346aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&vc_lock);
347aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&pvc->vc_state_lock);
348aecfc01dSrui zang - Sun Microsystems - Beijing China 
349aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!(pvc->vc_flags & WCS_ISOPEN)) {
350aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
351aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * vc_tem might not be intialized if !tems.ts_initialized,
352aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * and this only happens during console configuration.
353aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
354*5c22bad5SToomas Soome 		pvc->vc_tem = tem_init(crp, rq);
355aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
356aecfc01dSrui zang - Sun Microsystems - Beijing China 
357aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!(pvc->vc_flags & WCS_INIT))
358aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_init_tty(pvc);
359aecfc01dSrui zang - Sun Microsystems - Beijing China 
360aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
361aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * In normal case, the first screen is the system console;
362aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * In tipline case, the first screen is the first VT that gets started.
363aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
364aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (vc_active_console == VT_MINOR_INVALID && minor != VT_DAEMON_MINOR)
365aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (minor == 0 || consmode == CONS_KFB) {
366aecfc01dSrui zang - Sun Microsystems - Beijing China 			boolean_t unblank = B_FALSE;
367aecfc01dSrui zang - Sun Microsystems - Beijing China 
368aecfc01dSrui zang - Sun Microsystems - Beijing China 			vc_active_console = minor;
369aecfc01dSrui zang - Sun Microsystems - Beijing China 			vc_last_console = minor;
370aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (minor != 0) {
371aecfc01dSrui zang - Sun Microsystems - Beijing China 				/*
372aecfc01dSrui zang - Sun Microsystems - Beijing China 				 * If we are not opening the system console
373aecfc01dSrui zang - Sun Microsystems - Beijing China 				 * as the first console, clear the phyical
374aecfc01dSrui zang - Sun Microsystems - Beijing China 				 * screen.
375aecfc01dSrui zang - Sun Microsystems - Beijing China 				 */
376aecfc01dSrui zang - Sun Microsystems - Beijing China 				unblank = B_TRUE;
377aecfc01dSrui zang - Sun Microsystems - Beijing China 			}
378aecfc01dSrui zang - Sun Microsystems - Beijing China 
379aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_activate(pvc->vc_tem, unblank, crp);
380aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
381aecfc01dSrui zang - Sun Microsystems - Beijing China 
382aecfc01dSrui zang - Sun Microsystems - Beijing China 	if ((pvc->vc_ttycommon.t_flags & TS_XCLUDE) &&
383aecfc01dSrui zang - Sun Microsystems - Beijing China 	    (secpolicy_excl_open(crp) != 0)) {
384aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&pvc->vc_state_lock);
385aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&vc_lock);
386aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EBUSY);
387aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
388aecfc01dSrui zang - Sun Microsystems - Beijing China 
389aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor > vc_inuse_max_minor)
390aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_inuse_max_minor = minor;
391aecfc01dSrui zang - Sun Microsystems - Beijing China 
392aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_flags |= WCS_ISOPEN;
393aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_ttycommon.t_readq = rq;
394aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_ttycommon.t_writeq = WR(rq);
395aecfc01dSrui zang - Sun Microsystems - Beijing China 
396aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&pvc->vc_state_lock);
397aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vc_lock);
398aecfc01dSrui zang - Sun Microsystems - Beijing China 
399aecfc01dSrui zang - Sun Microsystems - Beijing China 	rq->q_ptr = pvc;
400aecfc01dSrui zang - Sun Microsystems - Beijing China 	WR(rq)->q_ptr = pvc;
401aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_wq = WR(rq);
402aecfc01dSrui zang - Sun Microsystems - Beijing China 
403aecfc01dSrui zang - Sun Microsystems - Beijing China 	qprocson(rq);
404aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (0);
405aecfc01dSrui zang - Sun Microsystems - Beijing China }
406aecfc01dSrui zang - Sun Microsystems - Beijing China 
407aecfc01dSrui zang - Sun Microsystems - Beijing China static minor_t
vt_find_prev(minor_t cur)408aecfc01dSrui zang - Sun Microsystems - Beijing China vt_find_prev(minor_t cur)
409aecfc01dSrui zang - Sun Microsystems - Beijing China {
410aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t i, t, max;
411aecfc01dSrui zang - Sun Microsystems - Beijing China 
412aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(vc_active_console != VT_MINOR_INVALID);
413aecfc01dSrui zang - Sun Microsystems - Beijing China 
414aecfc01dSrui zang - Sun Microsystems - Beijing China 	max = VC_INSTANCES_COUNT;
415aecfc01dSrui zang - Sun Microsystems - Beijing China 
416aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = cur - 1; (t = (i + max) % max) != cur; i--)
417aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!VT_IS_DAEMON(t) && VT_IS_INUSE(t))
418aecfc01dSrui zang - Sun Microsystems - Beijing China 			return (t);
419aecfc01dSrui zang - Sun Microsystems - Beijing China 
420aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (VT_MINOR_INVALID);
421aecfc01dSrui zang - Sun Microsystems - Beijing China }
422aecfc01dSrui zang - Sun Microsystems - Beijing China 
423aecfc01dSrui zang - Sun Microsystems - Beijing China static minor_t
vt_find_next(minor_t cur)424aecfc01dSrui zang - Sun Microsystems - Beijing China vt_find_next(minor_t cur)
425aecfc01dSrui zang - Sun Microsystems - Beijing China {
426aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t i, t, max;
427aecfc01dSrui zang - Sun Microsystems - Beijing China 
428aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(vc_active_console != VT_MINOR_INVALID);
429aecfc01dSrui zang - Sun Microsystems - Beijing China 
430aecfc01dSrui zang - Sun Microsystems - Beijing China 	max = VC_INSTANCES_COUNT;
431aecfc01dSrui zang - Sun Microsystems - Beijing China 
432aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = cur + 1; (t = (i + max) % max) != cur; i++)
433aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!VT_IS_DAEMON(t) && VT_IS_INUSE(t))
434aecfc01dSrui zang - Sun Microsystems - Beijing China 			return (t);
435aecfc01dSrui zang - Sun Microsystems - Beijing China 
436aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (VT_MINOR_INVALID);
437aecfc01dSrui zang - Sun Microsystems - Beijing China }
438aecfc01dSrui zang - Sun Microsystems - Beijing China 
439aecfc01dSrui zang - Sun Microsystems - Beijing China /* ARGSUSED */
440aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_send_hotkeys(void * timeout_arg)441aecfc01dSrui zang - Sun Microsystems - Beijing China vt_send_hotkeys(void *timeout_arg)
442aecfc01dSrui zang - Sun Microsystems - Beijing China {
443aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_handle_t door;
444aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_cmd_arg_t arg;
445aecfc01dSrui zang - Sun Microsystems - Beijing China 	int error = 0;
446aecfc01dSrui zang - Sun Microsystems - Beijing China 	int retries = 0;
447aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg_t door_arg;
448aecfc01dSrui zang - Sun Microsystems - Beijing China 
449aecfc01dSrui zang - Sun Microsystems - Beijing China 	arg.vt_ev = VT_EV_HOTKEYS;
45022af26cbSlipeng sang - Sun Microsystems - Beijing China 
45122af26cbSlipeng sang - Sun Microsystems - Beijing China 	mutex_enter(&vt_pending_vtno_lock);
452aecfc01dSrui zang - Sun Microsystems - Beijing China 	arg.vt_num = vt_pending_vtno;
45322af26cbSlipeng sang - Sun Microsystems - Beijing China 	mutex_exit(&vt_pending_vtno_lock);
454aecfc01dSrui zang - Sun Microsystems - Beijing China 
455aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* only available in kernel context or user context */
456aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (door_ki_open(VT_DAEMON_DOOR_FILE, &door) != 0) {
45722af26cbSlipeng sang - Sun Microsystems - Beijing China 		mutex_enter(&vt_pending_vtno_lock);
458aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_pending_vtno = -1;
459aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&vt_pending_vtno_lock);
460aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
461aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
462aecfc01dSrui zang - Sun Microsystems - Beijing China 
463aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.rbuf = NULL;
464aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.rsize = 0;
465aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.data_ptr = (void *)&arg;
466aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.data_size = sizeof (arg);
467aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.desc_ptr = NULL;
468aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_arg.desc_num = 0;
469aecfc01dSrui zang - Sun Microsystems - Beijing China 
470aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
471aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Make door upcall
472aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
473aecfc01dSrui zang - Sun Microsystems - Beijing China 	while ((error = door_ki_upcall(door, &door_arg)) != 0 &&
474aecfc01dSrui zang - Sun Microsystems - Beijing China 	    retries < VT_DOORCALL_MAX_RETRY)
475aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (error == EAGAIN || error == EINTR)
476aecfc01dSrui zang - Sun Microsystems - Beijing China 			retries++;
477aecfc01dSrui zang - Sun Microsystems - Beijing China 		else
478aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
479aecfc01dSrui zang - Sun Microsystems - Beijing China 
480aecfc01dSrui zang - Sun Microsystems - Beijing China 	door_ki_rele(door);
481aecfc01dSrui zang - Sun Microsystems - Beijing China 
48222af26cbSlipeng sang - Sun Microsystems - Beijing China 	mutex_enter(&vt_pending_vtno_lock);
483aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_pending_vtno = -1;
484aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vt_pending_vtno_lock);
485aecfc01dSrui zang - Sun Microsystems - Beijing China }
486aecfc01dSrui zang - Sun Microsystems - Beijing China 
487aecfc01dSrui zang - Sun Microsystems - Beijing China static boolean_t
vt_validate_hotkeys(int minor)488aecfc01dSrui zang - Sun Microsystems - Beijing China vt_validate_hotkeys(int minor)
489aecfc01dSrui zang - Sun Microsystems - Beijing China {
490aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
491aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * minor should not succeed the existing minor numbers range.
492aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
493aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!vt_minor_valid(minor))
494aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (B_FALSE);
495aecfc01dSrui zang - Sun Microsystems - Beijing China 
496aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
497aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Shouldn't switch to /dev/vt/1 or an unused vt.
498aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
499aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!VT_IS_DAEMON(minor) && VT_IS_INUSE(minor))
500aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (B_TRUE);
501aecfc01dSrui zang - Sun Microsystems - Beijing China 
502aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (B_FALSE);
503aecfc01dSrui zang - Sun Microsystems - Beijing China }
504aecfc01dSrui zang - Sun Microsystems - Beijing China 
505aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_trigger_hotkeys(int vtno)506aecfc01dSrui zang - Sun Microsystems - Beijing China vt_trigger_hotkeys(int vtno)
507aecfc01dSrui zang - Sun Microsystems - Beijing China {
508aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&vt_pending_vtno_lock);
509aecfc01dSrui zang - Sun Microsystems - Beijing China 
510aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (vt_pending_vtno != -1) {
511aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&vt_pending_vtno_lock);
512aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
513aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
514aecfc01dSrui zang - Sun Microsystems - Beijing China 
515aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_pending_vtno = vtno;
516aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vt_pending_vtno_lock);
517aecfc01dSrui zang - Sun Microsystems - Beijing China 	(void) timeout(vt_send_hotkeys, NULL, 1);
518aecfc01dSrui zang - Sun Microsystems - Beijing China }
519aecfc01dSrui zang - Sun Microsystems - Beijing China 
520aecfc01dSrui zang - Sun Microsystems - Beijing China /*
521aecfc01dSrui zang - Sun Microsystems - Beijing China  * return value:
522aecfc01dSrui zang - Sun Microsystems - Beijing China  *    0:    non msg of vt hotkeys
523aecfc01dSrui zang - Sun Microsystems - Beijing China  *    1:    msg of vt hotkeys
524aecfc01dSrui zang - Sun Microsystems - Beijing China  */
525aecfc01dSrui zang - Sun Microsystems - Beijing China int
vt_check_hotkeys(mblk_t * mp)526aecfc01dSrui zang - Sun Microsystems - Beijing China vt_check_hotkeys(mblk_t *mp)
527aecfc01dSrui zang - Sun Microsystems - Beijing China {
528aecfc01dSrui zang - Sun Microsystems - Beijing China 	int vtno = 0;
529aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t minor = 0;
530aecfc01dSrui zang - Sun Microsystems - Beijing China 
531aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* LINTED E_PTRDIFF_OVERFLOW */
532aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!VT_MSG_SWITCH(mp))
533aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
534aecfc01dSrui zang - Sun Microsystems - Beijing China 
535aecfc01dSrui zang - Sun Microsystems - Beijing China 	switch (VT_MSG_OPCODE(mp)) {
536aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 'B':
537aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* find out the previous vt */
538aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (vc_active_console == VT_MINOR_INVALID)
539aecfc01dSrui zang - Sun Microsystems - Beijing China 			return (1);
540aecfc01dSrui zang - Sun Microsystems - Beijing China 
541aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (VT_IS_DAEMON(vc_active_console)) {
542aecfc01dSrui zang - Sun Microsystems - Beijing China 			minor = vt_find_prev(vt_arg2minor(vc_target_console));
543aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
544aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
545aecfc01dSrui zang - Sun Microsystems - Beijing China 
546aecfc01dSrui zang - Sun Microsystems - Beijing China 		minor = vt_find_prev(vc_active_console);
547aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
548aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 'F':
549aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* find out the next vt */
550aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (vc_active_console == VT_MINOR_INVALID)
551aecfc01dSrui zang - Sun Microsystems - Beijing China 			return (1);
552aecfc01dSrui zang - Sun Microsystems - Beijing China 
553aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (VT_IS_DAEMON(vc_active_console)) {
554aecfc01dSrui zang - Sun Microsystems - Beijing China 			minor = vt_find_next(vt_arg2minor(vc_target_console));
555aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
556aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
557aecfc01dSrui zang - Sun Microsystems - Beijing China 
558aecfc01dSrui zang - Sun Microsystems - Beijing China 		minor = vt_find_next(vc_active_console);
559aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
560aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 'H':
561aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* find out the specified vt */
562aecfc01dSrui zang - Sun Microsystems - Beijing China 		minor = VT_MSG_VTNO(mp);
563aecfc01dSrui zang - Sun Microsystems - Beijing China 
564aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* check for system console, Alt + F1 */
565aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (minor == 1)
566aecfc01dSrui zang - Sun Microsystems - Beijing China 			minor = 0;
567aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
568aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 'L':
569aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* find out the last vt */
570aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((minor = vc_last_console) == VT_MINOR_INVALID)
571aecfc01dSrui zang - Sun Microsystems - Beijing China 			return (1);
572aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
573aecfc01dSrui zang - Sun Microsystems - Beijing China 	default:
574aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (1);
575aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
576aecfc01dSrui zang - Sun Microsystems - Beijing China 
577aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!vt_validate_hotkeys(minor))
578aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (1);
579aecfc01dSrui zang - Sun Microsystems - Beijing China 
580aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
581aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * for system console, the argument of vtno for
582aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * vt_activate is 1, though its minor is 0
583aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
584aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor == 0)
585aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtno = 1;	/* for system console */
586aecfc01dSrui zang - Sun Microsystems - Beijing China 	else
587aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtno = minor;
588aecfc01dSrui zang - Sun Microsystems - Beijing China 
589aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_trigger_hotkeys(vtno);
590aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (1);
591aecfc01dSrui zang - Sun Microsystems - Beijing China }
592aecfc01dSrui zang - Sun Microsystems - Beijing China 
593aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_proc_sendsig(pid_t pid,int sig)594aecfc01dSrui zang - Sun Microsystems - Beijing China vt_proc_sendsig(pid_t pid, int sig)
595aecfc01dSrui zang - Sun Microsystems - Beijing China {
596aecfc01dSrui zang - Sun Microsystems - Beijing China 	register proc_t *p;
597aecfc01dSrui zang - Sun Microsystems - Beijing China 
598aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pid <= 0)
599aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
600aecfc01dSrui zang - Sun Microsystems - Beijing China 
601aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&pidlock);
602aecfc01dSrui zang - Sun Microsystems - Beijing China 	if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
603aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&pidlock);
604aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
605aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
606aecfc01dSrui zang - Sun Microsystems - Beijing China 
607aecfc01dSrui zang - Sun Microsystems - Beijing China 	psignal(p, sig);
608aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&pidlock);
609aecfc01dSrui zang - Sun Microsystems - Beijing China }
610aecfc01dSrui zang - Sun Microsystems - Beijing China 
611aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vt_proc_exists(pid_t pid)612aecfc01dSrui zang - Sun Microsystems - Beijing China vt_proc_exists(pid_t pid)
613aecfc01dSrui zang - Sun Microsystems - Beijing China {
614aecfc01dSrui zang - Sun Microsystems - Beijing China 	register proc_t *p;
615aecfc01dSrui zang - Sun Microsystems - Beijing China 
616aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pid <= 0)
617aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EINVAL);
618aecfc01dSrui zang - Sun Microsystems - Beijing China 
619aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&pidlock);
620aecfc01dSrui zang - Sun Microsystems - Beijing China 	if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
621aecfc01dSrui zang - Sun Microsystems - Beijing China 		mutex_exit(&pidlock);
622aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ESRCH);
623aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
624aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&pidlock);
625aecfc01dSrui zang - Sun Microsystems - Beijing China 
626aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (0);
627aecfc01dSrui zang - Sun Microsystems - Beijing China }
628aecfc01dSrui zang - Sun Microsystems - Beijing China 
629bdf0047cSRoger A. Faulkner #define	SIG_VALID(x)	(((x) > 0) && ((x) <= MAXSIG) && \
630aecfc01dSrui zang - Sun Microsystems - Beijing China 			((x) != SIGKILL) && ((x) != SIGSTOP))
631aecfc01dSrui zang - Sun Microsystems - Beijing China 
632aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vt_setmode(vc_state_t * pvc,struct vt_mode * pmode)633aecfc01dSrui zang - Sun Microsystems - Beijing China vt_setmode(vc_state_t *pvc, struct vt_mode *pmode)
634aecfc01dSrui zang - Sun Microsystems - Beijing China {
635aecfc01dSrui zang - Sun Microsystems - Beijing China 	if ((pmode->mode != VT_PROCESS) && (pmode->mode != VT_AUTO))
636aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EINVAL);
637aecfc01dSrui zang - Sun Microsystems - Beijing China 
638aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!SIG_VALID(pmode->relsig) || !SIG_VALID(pmode->acqsig))
639aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EINVAL);
640aecfc01dSrui zang - Sun Microsystems - Beijing China 
641aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pmode->mode == VT_PROCESS) {
642aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_pid = curproc->p_pid;
643aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else {
644aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_dispnum = 0;
645aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_login = 0;
646aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
647aecfc01dSrui zang - Sun Microsystems - Beijing China 
648aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_switch_mode = pmode->mode;
649aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_waitv = pmode->waitv;
650aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_relsig = pmode->relsig;
651aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_acqsig = pmode->acqsig;
652aecfc01dSrui zang - Sun Microsystems - Beijing China 
653aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (0);
654aecfc01dSrui zang - Sun Microsystems - Beijing China }
655aecfc01dSrui zang - Sun Microsystems - Beijing China 
656aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_reset(vc_state_t * pvc)657aecfc01dSrui zang - Sun Microsystems - Beijing China vt_reset(vc_state_t *pvc)
658aecfc01dSrui zang - Sun Microsystems - Beijing China {
659aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_switch_mode = VT_AUTO;
660aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_pid = -1;
661aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_dispnum = 0;
662aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_login = 0;
663aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_switchto = VT_MINOR_INVALID;
664aecfc01dSrui zang - Sun Microsystems - Beijing China }
665aecfc01dSrui zang - Sun Microsystems - Beijing China 
666aecfc01dSrui zang - Sun Microsystems - Beijing China /*
667aecfc01dSrui zang - Sun Microsystems - Beijing China  * switch to vt_no from vc_active_console
668aecfc01dSrui zang - Sun Microsystems - Beijing China  */
669cc831366Srui zang - Sun Microsystems - Beijing China static int
vt_switch(uint_t vt_no,cred_t * credp)670aecfc01dSrui zang - Sun Microsystems - Beijing China vt_switch(uint_t vt_no, cred_t *credp)
671aecfc01dSrui zang - Sun Microsystems - Beijing China {
672aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc_active = vt_minor2vc(vc_active_console);
673aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc = vt_minor2vc(vt_no);
674aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t index;
675aecfc01dSrui zang - Sun Microsystems - Beijing China 
676aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(pvc_active && pvc);
677aecfc01dSrui zang - Sun Microsystems - Beijing China 
678cc831366Srui zang - Sun Microsystems - Beijing China 	/* sanity test for the target VT and the active VT */
679cc831366Srui zang - Sun Microsystems - Beijing China 	if (!((pvc->vc_flags & WCS_ISOPEN) && (pvc->vc_flags & WCS_INIT)))
680cc831366Srui zang - Sun Microsystems - Beijing China 		return (EINVAL);
681cc831366Srui zang - Sun Microsystems - Beijing China 
682cc831366Srui zang - Sun Microsystems - Beijing China 	if (!((pvc_active->vc_flags & WCS_ISOPEN) &&
683cc831366Srui zang - Sun Microsystems - Beijing China 	    (pvc_active->vc_flags & WCS_INIT)))
684cc831366Srui zang - Sun Microsystems - Beijing China 		return (EINVAL);
685cc831366Srui zang - Sun Microsystems - Beijing China 
686aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&vc_lock);
687aecfc01dSrui zang - Sun Microsystems - Beijing China 
688aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_switch(pvc_active->vc_tem, pvc->vc_tem, credp);
689aecfc01dSrui zang - Sun Microsystems - Beijing China 
690aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!VT_IS_DAEMON(vc_active_console))
691aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_last_console = vc_active_console;
692aecfc01dSrui zang - Sun Microsystems - Beijing China 	else
693aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_last_console = vt_arg2minor(vc_target_console);
694aecfc01dSrui zang - Sun Microsystems - Beijing China 
695aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_active_console = pvc->vc_minor;
696aecfc01dSrui zang - Sun Microsystems - Beijing China 
697aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc->vc_switch_mode == VT_PROCESS) {
698aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_switchto = pvc->vc_minor;
699aecfc01dSrui zang - Sun Microsystems - Beijing China 
700aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* send it an acquired signal */
701aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_proc_sendsig(pvc->vc_pid, pvc->vc_acqsig);
702aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
703aecfc01dSrui zang - Sun Microsystems - Beijing China 
704aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_waitactive_reply(vc_active_console, B_FALSE);
705aecfc01dSrui zang - Sun Microsystems - Beijing China 
706aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vc_lock);
707aecfc01dSrui zang - Sun Microsystems - Beijing China 
708aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!VT_IS_DAEMON(vt_no)) {
709aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
710aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Applications that open the virtual console device may request
711aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * asynchronous notification of VT switching from a previous VT
712aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * to another one by setting the S_MSG flag in an I_SETSIG
713aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * STREAMS ioctl. Such processes receive a SIGPOLL signal when
714aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * a VT switching succeeds.
715aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
716aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (index = 0; index < VC_INSTANCES_COUNT; index++) {
717aecfc01dSrui zang - Sun Microsystems - Beijing China 			vc_state_t *tmp_pvc = vt_minor2vc(index);
718aecfc01dSrui zang - Sun Microsystems - Beijing China 			mblk_t *mp;
719aecfc01dSrui zang - Sun Microsystems - Beijing China 
720aecfc01dSrui zang - Sun Microsystems - Beijing China 			if ((tmp_pvc->vc_flags & WCS_ISOPEN) &&
721aecfc01dSrui zang - Sun Microsystems - Beijing China 			    (tmp_pvc->vc_flags & WCS_INIT) &&
722aecfc01dSrui zang - Sun Microsystems - Beijing China 			    (mp = allocb(sizeof (unsigned char), BPRI_HI))) {
723aecfc01dSrui zang - Sun Microsystems - Beijing China 				mp->b_datap->db_type = M_PCSIG;
724aecfc01dSrui zang - Sun Microsystems - Beijing China 				*mp->b_wptr = SIGPOLL;
725aecfc01dSrui zang - Sun Microsystems - Beijing China 				mp->b_wptr += sizeof (unsigned char);
726aecfc01dSrui zang - Sun Microsystems - Beijing China 				putnext(RD(tmp_pvc->vc_wq), mp);
727aecfc01dSrui zang - Sun Microsystems - Beijing China 			}
728aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
729aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
730aecfc01dSrui zang - Sun Microsystems - Beijing China 
731cc831366Srui zang - Sun Microsystems - Beijing China 	return (0);
732cc831366Srui zang - Sun Microsystems - Beijing China 
733aecfc01dSrui zang - Sun Microsystems - Beijing China }
734aecfc01dSrui zang - Sun Microsystems - Beijing China 
735aecfc01dSrui zang - Sun Microsystems - Beijing China /*
736aecfc01dSrui zang - Sun Microsystems - Beijing China  * vt_no	from 0 to n
737aecfc01dSrui zang - Sun Microsystems - Beijing China  *
738aecfc01dSrui zang - Sun Microsystems - Beijing China  * 0	for the vtdaemon sepcial console (only vtdaemon will use it)
739aecfc01dSrui zang - Sun Microsystems - Beijing China  * 1    for the system console (Alt + F1, or Alt + Ctrl + F1),
740aecfc01dSrui zang - Sun Microsystems - Beijing China  *      aka Virtual Console #1
741aecfc01dSrui zang - Sun Microsystems - Beijing China  *
742aecfc01dSrui zang - Sun Microsystems - Beijing China  * 2    for Virtual Console #2
743aecfc01dSrui zang - Sun Microsystems - Beijing China  * n    for Virtual Console #n
744aecfc01dSrui zang - Sun Microsystems - Beijing China  */
745aecfc01dSrui zang - Sun Microsystems - Beijing China static minor_t
vt_arg2minor(uint_t arg)746aecfc01dSrui zang - Sun Microsystems - Beijing China vt_arg2minor(uint_t arg)
747aecfc01dSrui zang - Sun Microsystems - Beijing China {
748aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (arg == 0)
749aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (1);
750aecfc01dSrui zang - Sun Microsystems - Beijing China 
751aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (arg == 1)
752aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
753aecfc01dSrui zang - Sun Microsystems - Beijing China 
754aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (arg);
755aecfc01dSrui zang - Sun Microsystems - Beijing China }
756aecfc01dSrui zang - Sun Microsystems - Beijing China 
757aecfc01dSrui zang - Sun Microsystems - Beijing China static uint_t
vt_minor2arg(minor_t minor)758aecfc01dSrui zang - Sun Microsystems - Beijing China vt_minor2arg(minor_t minor)
759aecfc01dSrui zang - Sun Microsystems - Beijing China {
760aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor == 0)
761aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (1);
762aecfc01dSrui zang - Sun Microsystems - Beijing China 
763aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (VT_IS_DAEMON(minor)) {
764aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* here it should be the real console */
765aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (vc_target_console);
766aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
767aecfc01dSrui zang - Sun Microsystems - Beijing China 
768aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (minor);
769aecfc01dSrui zang - Sun Microsystems - Beijing China }
770aecfc01dSrui zang - Sun Microsystems - Beijing China 
771aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vt_activate(uint_t vt_no,cred_t * credp)772aecfc01dSrui zang - Sun Microsystems - Beijing China vt_activate(uint_t vt_no, cred_t *credp)
773aecfc01dSrui zang - Sun Microsystems - Beijing China {
774aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc;
775aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t minor;
776aecfc01dSrui zang - Sun Microsystems - Beijing China 
777aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor = vt_arg2minor(vt_no);
778aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!vt_minor_valid(minor))
779aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
780aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor == vc_active_console) {
781aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (VT_IS_DAEMON(minor)) {
782aecfc01dSrui zang - Sun Microsystems - Beijing China 			/*
783aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * vtdaemon is reactivating itself to do locking
784aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * on behalf of another console, so record current
785aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * target console as the last console.
786aecfc01dSrui zang - Sun Microsystems - Beijing China 			 */
787aecfc01dSrui zang - Sun Microsystems - Beijing China 			vc_last_console = vt_arg2minor(vc_target_console);
788aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
789aecfc01dSrui zang - Sun Microsystems - Beijing China 
790aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
791aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
792aecfc01dSrui zang - Sun Microsystems - Beijing China 
793aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
794aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * In tipline case, the system console is redirected to tipline
795aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * and thus is always available.
796aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
797aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor == 0 && consconfig_console_is_tipline())
798aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
799aecfc01dSrui zang - Sun Microsystems - Beijing China 
800aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!VT_IS_INUSE(minor))
801aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
802aecfc01dSrui zang - Sun Microsystems - Beijing China 
803aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc = vt_minor2vc(minor);
804aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc == NULL)
805aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
806aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc->vc_tem == NULL)
807aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
808aecfc01dSrui zang - Sun Microsystems - Beijing China 
809aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc = vt_minor2vc(vc_active_console);
810aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc == NULL)
811aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (ENXIO);
812cc831366Srui zang - Sun Microsystems - Beijing China 	if (pvc->vc_switch_mode != VT_PROCESS)
813cc831366Srui zang - Sun Microsystems - Beijing China 		return (vt_switch(minor, credp));
814aecfc01dSrui zang - Sun Microsystems - Beijing China 
815aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
816aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Validate the process, reset the
817aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * vt to auto mode if failed.
818aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
819aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (pvc->vc_pid == -1 || vt_proc_exists(pvc->vc_pid) != 0) {
820aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
821aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Xserver has not started up yet,
822aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * or it dose not exist.
823aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
824aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_reset(pvc);
825aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
826aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
827aecfc01dSrui zang - Sun Microsystems - Beijing China 
828aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
829aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Send the release signal to the process,
830aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * and wait VT_RELDISP ioctl from Xserver
831aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * after its leaving VT.
832aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
833aecfc01dSrui zang - Sun Microsystems - Beijing China 	vt_proc_sendsig(pvc->vc_pid, pvc->vc_relsig);
834aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_switchto = minor;
835aecfc01dSrui zang - Sun Microsystems - Beijing China 
836aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
837aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * We don't need a timeout here, for if Xserver refuses
838aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * or fails to respond to release signal using VT_RELDISP,
839aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * we cannot successfully switch to our text mode. Actually
840aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * users can try again. At present we don't support force
841aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * switch.
842aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
843aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (0);
844aecfc01dSrui zang - Sun Microsystems - Beijing China }
845aecfc01dSrui zang - Sun Microsystems - Beijing China 
846aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vt_reldisp(vc_state_t * pvc,int arg,cred_t * credp)847aecfc01dSrui zang - Sun Microsystems - Beijing China vt_reldisp(vc_state_t *pvc, int arg, cred_t *credp)
848aecfc01dSrui zang - Sun Microsystems - Beijing China {
849aecfc01dSrui zang - Sun Microsystems - Beijing China 	minor_t target_vtno = pvc->vc_switchto;
850aecfc01dSrui zang - Sun Microsystems - Beijing China 
851aecfc01dSrui zang - Sun Microsystems - Beijing China 	if ((pvc->vc_switch_mode != VT_PROCESS) ||
852aecfc01dSrui zang - Sun Microsystems - Beijing China 	    (pvc->vc_minor != vc_active_console))
853aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EACCES);
854aecfc01dSrui zang - Sun Microsystems - Beijing China 
855aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (target_vtno == VT_MINOR_INVALID)
856aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (EINVAL);
857aecfc01dSrui zang - Sun Microsystems - Beijing China 
858aecfc01dSrui zang - Sun Microsystems - Beijing China 	pvc->vc_switchto = VT_MINOR_INVALID;
859aecfc01dSrui zang - Sun Microsystems - Beijing China 
860aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (arg == VT_ACKACQ)
861aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
862aecfc01dSrui zang - Sun Microsystems - Beijing China 
863aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (arg == 0)
864aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0); /* refuse to release */
865aecfc01dSrui zang - Sun Microsystems - Beijing China 
866aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* Xserver has left VT */
867cc831366Srui zang - Sun Microsystems - Beijing China 	return (vt_switch(target_vtno, credp));
868aecfc01dSrui zang - Sun Microsystems - Beijing China }
869aecfc01dSrui zang - Sun Microsystems - Beijing China 
870aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_ioctl(queue_t * q,mblk_t * mp)871aecfc01dSrui zang - Sun Microsystems - Beijing China vt_ioctl(queue_t *q, mblk_t *mp)
872aecfc01dSrui zang - Sun Microsystems - Beijing China {
873aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc = (vc_state_t *)q->q_ptr;
874aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct iocblk	*iocp;
875aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct vt_mode vtmode;
876aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct vt_stat vtinfo;
877aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct vt_dispinfo vtdisp;
878aecfc01dSrui zang - Sun Microsystems - Beijing China 	mblk_t *tmp;
879aecfc01dSrui zang - Sun Microsystems - Beijing China 	int minor;
880aecfc01dSrui zang - Sun Microsystems - Beijing China 	int arg;
881aecfc01dSrui zang - Sun Microsystems - Beijing China 	int error = 0;
882aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_waitactive_msg_t *wait_msg;
883aecfc01dSrui zang - Sun Microsystems - Beijing China 
884aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocp = (struct iocblk *)(void *)mp->b_rptr;
885aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (consmode != CONS_KFB && iocp->ioc_cmd != VT_ENABLED) {
886aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocnak(q, mp, EINVAL);
887aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
888aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
889aecfc01dSrui zang - Sun Microsystems - Beijing China 
890aecfc01dSrui zang - Sun Microsystems - Beijing China 	switch (iocp->ioc_cmd) {
891aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_ENABLED:
892aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (int), BPRI_MED))) {
893aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
894aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
895aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
896aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(int *)(void *)tmp->b_rptr = consmode;
897aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (int);
898aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (int));
899aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
900aecfc01dSrui zang - Sun Microsystems - Beijing China 
901aecfc01dSrui zang - Sun Microsystems - Beijing China 	case KDSETMODE:
902aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
903aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (arg != KD_TEXT && arg != KD_GRAPHICS) {
904aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = EINVAL;
905aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
906aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
907aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem_get_fbmode(pvc->vc_tem) == arg)
908aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
909aecfc01dSrui zang - Sun Microsystems - Beijing China 
910aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_set_fbmode(pvc->vc_tem, (uchar_t)arg, iocp->ioc_cr);
911aecfc01dSrui zang - Sun Microsystems - Beijing China 
912aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
913aecfc01dSrui zang - Sun Microsystems - Beijing China 
914aecfc01dSrui zang - Sun Microsystems - Beijing China 	case KDGETMODE:
915aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (int), BPRI_MED))) {
916aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
917aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
918aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
919aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(int *)(void *)tmp->b_rptr = tem_get_fbmode(pvc->vc_tem);
920aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (int);
921aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (int));
922aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
923aecfc01dSrui zang - Sun Microsystems - Beijing China 
924aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_OPENQRY: /* return number of first free VT */
925aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (int), BPRI_MED))) {
926aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
927aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
928aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
929aecfc01dSrui zang - Sun Microsystems - Beijing China 
930aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* minors of 0 and 1 are not available to end users */
931aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (minor = 2; vt_minor_valid(minor); minor++)
932aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (!VT_IS_INUSE(minor))
933aecfc01dSrui zang - Sun Microsystems - Beijing China 				break;
934aecfc01dSrui zang - Sun Microsystems - Beijing China 
935aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!vt_minor_valid(minor))
936aecfc01dSrui zang - Sun Microsystems - Beijing China 			minor = -1;
937aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(int *)(void *)tmp->b_rptr = minor; /* /dev/vt/minor */
938aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (int);
939aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (int));
940aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
941aecfc01dSrui zang - Sun Microsystems - Beijing China 
942aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETMODE:
943aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtmode.mode = pvc->vc_switch_mode;
944aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtmode.waitv = pvc->vc_waitv;
945aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtmode.relsig = pvc->vc_relsig;
946aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtmode.acqsig = pvc->vc_acqsig;
947aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtmode.frsig = 0;
948aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (struct vt_mode), BPRI_MED))) {
949aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
950aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
951aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
952aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(struct vt_mode *)(void *)tmp->b_rptr = vtmode;
953aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (struct vt_mode);
954aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (struct vt_mode));
955aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
956aecfc01dSrui zang - Sun Microsystems - Beijing China 
957aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_SETMODE:
958aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyin(q, mp, sizeof (struct vt_mode));
959aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
960aecfc01dSrui zang - Sun Microsystems - Beijing China 
961aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_SETDISPINFO:
962aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege for setdispinfo */
963aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
964aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
965aecfc01dSrui zang - Sun Microsystems - Beijing China 
966aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_dispnum = *(intptr_t *)(void *)mp->b_cont->b_rptr;
967aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
968aecfc01dSrui zang - Sun Microsystems - Beijing China 
969aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_SETDISPLOGIN:
970aecfc01dSrui zang - Sun Microsystems - Beijing China 		pvc->vc_login = *(intptr_t *)(void *)mp->b_cont->b_rptr;
971aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
972aecfc01dSrui zang - Sun Microsystems - Beijing China 
973aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETDISPINFO:
974aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtdisp.v_pid = pvc->vc_pid;
975aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtdisp.v_dispnum = pvc->vc_dispnum;
976aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtdisp.v_login = pvc->vc_login;
977aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (struct vt_dispinfo), BPRI_MED))) {
978aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
979aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
980aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
981aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(struct vt_dispinfo *)(void *)tmp->b_rptr = vtdisp;
982aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (struct vt_dispinfo);
983aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (struct vt_dispinfo));
984aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
985aecfc01dSrui zang - Sun Microsystems - Beijing China 
986aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_RELDISP:
987aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
988aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = vt_reldisp(pvc, arg, iocp->ioc_cr);
989aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
990aecfc01dSrui zang - Sun Microsystems - Beijing China 
991aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_CONFIG:
992aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege for config */
993aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
994aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
995aecfc01dSrui zang - Sun Microsystems - Beijing China 
996aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
997aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = vt_config(arg);
998aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
999aecfc01dSrui zang - Sun Microsystems - Beijing China 
1000aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_ACTIVATE:
1001aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege for secure switch */
1002aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
1003aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1004aecfc01dSrui zang - Sun Microsystems - Beijing China 
1005aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
1006aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = vt_activate(arg, iocp->ioc_cr);
1007aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1008aecfc01dSrui zang - Sun Microsystems - Beijing China 
1009aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_WAITACTIVE:
1010aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
1011aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = vt_arg2minor(arg);
1012aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!vt_minor_valid(arg)) {
1013aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENXIO;
1014aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1015aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1016aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (arg == vc_active_console)
1017aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1018aecfc01dSrui zang - Sun Microsystems - Beijing China 
1019aecfc01dSrui zang - Sun Microsystems - Beijing China 		wait_msg = kmem_zalloc(sizeof (vc_waitactive_msg_t),
1020aecfc01dSrui zang - Sun Microsystems - Beijing China 		    KM_NOSLEEP);
1021aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (wait_msg == NULL) {
1022aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENXIO;
1023aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1024aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1025aecfc01dSrui zang - Sun Microsystems - Beijing China 
1026aecfc01dSrui zang - Sun Microsystems - Beijing China 		wait_msg->wa_mp = mp;
1027aecfc01dSrui zang - Sun Microsystems - Beijing China 		wait_msg->wa_msg_minor = pvc->vc_minor;
1028aecfc01dSrui zang - Sun Microsystems - Beijing China 		wait_msg->wa_wait_minor = arg;
1029aecfc01dSrui zang - Sun Microsystems - Beijing China 		list_insert_head(&vc_waitactive_list, wait_msg);
1030aecfc01dSrui zang - Sun Microsystems - Beijing China 
1031aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1032aecfc01dSrui zang - Sun Microsystems - Beijing China 
1033aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETSTATE:
1034aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
1035aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Here v_active is the argument for vt_activate,
1036aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * not minor.
1037aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
1038aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtinfo.v_active = vt_minor2arg(vc_active_console);
1039aecfc01dSrui zang - Sun Microsystems - Beijing China 		vtinfo.v_state = 3;	/* system console and vtdaemon */
1040aecfc01dSrui zang - Sun Microsystems - Beijing China 
1041aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* we only support 16 vt states since the v_state is short */
1042aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (minor = 2; minor < 16; minor++) {
1043aecfc01dSrui zang - Sun Microsystems - Beijing China 			pvc = vt_minor2vc(minor);
1044aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (pvc == NULL)
1045aecfc01dSrui zang - Sun Microsystems - Beijing China 				break;
1046aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (VT_IS_INUSE(minor))
1047aecfc01dSrui zang - Sun Microsystems - Beijing China 				vtinfo.v_state |= (1 << pvc->vc_minor);
1048aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1049aecfc01dSrui zang - Sun Microsystems - Beijing China 
1050aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (struct vt_stat), BPRI_MED))) {
1051aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
1052aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1053aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1054aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(struct vt_stat *)(void *)tmp->b_rptr = vtinfo;
1055aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (struct vt_stat);
1056aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (struct vt_stat));
1057aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1058aecfc01dSrui zang - Sun Microsystems - Beijing China 
1059aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_SET_TARGET:
1060aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege */
1061aecfc01dSrui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
1062aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1063aecfc01dSrui zang - Sun Microsystems - Beijing China 
1064aecfc01dSrui zang - Sun Microsystems - Beijing China 		arg = *(intptr_t *)(void *)mp->b_cont->b_rptr;
1065aecfc01dSrui zang - Sun Microsystems - Beijing China 
1066aecfc01dSrui zang - Sun Microsystems - Beijing China 		/* vtdaemon is doing authentication for this target console */
1067aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_target_console = arg;
1068aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1069aecfc01dSrui zang - Sun Microsystems - Beijing China 
1070aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETACTIVE:	/* get real active console (minor) */
1071aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (int), BPRI_MED))) {
1072aecfc01dSrui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
1073aecfc01dSrui zang - Sun Microsystems - Beijing China 			break;
1074aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1075aecfc01dSrui zang - Sun Microsystems - Beijing China 		*(int *)(void *)tmp->b_rptr = vc_active_console;
1076aecfc01dSrui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (int);
1077aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (int));
1078aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1079aecfc01dSrui zang - Sun Microsystems - Beijing China 
1080ceeba6f9Srui zang - Sun Microsystems - Beijing China 	case VT_GET_CONSUSER:
1081ceeba6f9Srui zang - Sun Microsystems - Beijing China 		if (!(tmp = allocb(sizeof (int), BPRI_MED))) {
1082ceeba6f9Srui zang - Sun Microsystems - Beijing China 			error = ENOMEM;
1083ceeba6f9Srui zang - Sun Microsystems - Beijing China 			break;
1084ceeba6f9Srui zang - Sun Microsystems - Beijing China 		}
1085ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1086ceeba6f9Srui zang - Sun Microsystems - Beijing China 		if (vc_cons_user == VT_MINOR_INVALID) {
1087ceeba6f9Srui zang - Sun Microsystems - Beijing China 			/*
1088ceeba6f9Srui zang - Sun Microsystems - Beijing China 			 * Return -1 if console user link points to
1089ceeba6f9Srui zang - Sun Microsystems - Beijing China 			 * /dev/console
1090ceeba6f9Srui zang - Sun Microsystems - Beijing China 			 */
1091ceeba6f9Srui zang - Sun Microsystems - Beijing China 			*(int *)(void *)tmp->b_rptr = -1;
1092ceeba6f9Srui zang - Sun Microsystems - Beijing China 		} else {
1093ceeba6f9Srui zang - Sun Microsystems - Beijing China 			*(int *)(void *)tmp->b_rptr = vc_cons_user;
1094ceeba6f9Srui zang - Sun Microsystems - Beijing China 		}
1095ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1096ceeba6f9Srui zang - Sun Microsystems - Beijing China 		tmp->b_wptr += sizeof (int);
1097ceeba6f9Srui zang - Sun Microsystems - Beijing China 		vt_copyout(q, mp, tmp, sizeof (int));
1098ceeba6f9Srui zang - Sun Microsystems - Beijing China 		return;
1099ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1100ceeba6f9Srui zang - Sun Microsystems - Beijing China 	case VT_RESET_CONSUSER:
1101ceeba6f9Srui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege */
1102ceeba6f9Srui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
1103ceeba6f9Srui zang - Sun Microsystems - Beijing China 			break;
1104ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1105ceeba6f9Srui zang - Sun Microsystems - Beijing China 		/* Ensure it comes from /dev/console */
1106ceeba6f9Srui zang - Sun Microsystems - Beijing China 		if (pvc->vc_minor != 0) {
1107ceeba6f9Srui zang - Sun Microsystems - Beijing China 			error = ENXIO;
1108ceeba6f9Srui zang - Sun Microsystems - Beijing China 			break;
1109ceeba6f9Srui zang - Sun Microsystems - Beijing China 		}
1110ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1111ceeba6f9Srui zang - Sun Microsystems - Beijing China 		mutex_enter(&vc_lock);
1112ceeba6f9Srui zang - Sun Microsystems - Beijing China 		vc_cons_user = VT_MINOR_INVALID;
1113ceeba6f9Srui zang - Sun Microsystems - Beijing China 		mutex_exit(&vc_lock);
1114ceeba6f9Srui zang - Sun Microsystems - Beijing China 		break;
1115ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1116ceeba6f9Srui zang - Sun Microsystems - Beijing China 	case VT_SET_CONSUSER:
1117ceeba6f9Srui zang - Sun Microsystems - Beijing China 		/* always enforce sys_devices privilege */
1118ceeba6f9Srui zang - Sun Microsystems - Beijing China 		if ((error = secpolicy_console(iocp->ioc_cr)) != 0)
1119ceeba6f9Srui zang - Sun Microsystems - Beijing China 			break;
1120ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1121ceeba6f9Srui zang - Sun Microsystems - Beijing China 		mutex_enter(&vc_lock);
1122ceeba6f9Srui zang - Sun Microsystems - Beijing China 		vc_cons_user = pvc->vc_minor;
1123ceeba6f9Srui zang - Sun Microsystems - Beijing China 		mutex_exit(&vc_lock);
1124ceeba6f9Srui zang - Sun Microsystems - Beijing China 		break;
1125ceeba6f9Srui zang - Sun Microsystems - Beijing China 
1126aecfc01dSrui zang - Sun Microsystems - Beijing China 	default:
1127aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = ENXIO;
1128aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1129aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1130aecfc01dSrui zang - Sun Microsystems - Beijing China 
1131aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (error != 0)
1132aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocnak(q, mp, error);
1133aecfc01dSrui zang - Sun Microsystems - Beijing China 	else
1134aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocack(q, mp);
1135aecfc01dSrui zang - Sun Microsystems - Beijing China }
1136aecfc01dSrui zang - Sun Microsystems - Beijing China 
1137aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_miocdata(queue_t * qp,mblk_t * mp)1138aecfc01dSrui zang - Sun Microsystems - Beijing China vt_miocdata(queue_t *qp, mblk_t *mp)
1139aecfc01dSrui zang - Sun Microsystems - Beijing China {
1140aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t *pvc = (vc_state_t *)qp->q_ptr;
1141aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct copyresp *copyresp;
1142aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct vt_mode *pmode;
1143aecfc01dSrui zang - Sun Microsystems - Beijing China 	int error = 0;
1144aecfc01dSrui zang - Sun Microsystems - Beijing China 
1145aecfc01dSrui zang - Sun Microsystems - Beijing China 	copyresp = (struct copyresp *)(void *)mp->b_rptr;
1146aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (copyresp->cp_rval) {
1147aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocnak(qp, mp, EAGAIN);
1148aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1149aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1150aecfc01dSrui zang - Sun Microsystems - Beijing China 
1151aecfc01dSrui zang - Sun Microsystems - Beijing China 	switch (copyresp->cp_cmd) {
1152aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_SETMODE:
1153aecfc01dSrui zang - Sun Microsystems - Beijing China 		pmode = (struct vt_mode *)(void *)mp->b_cont->b_rptr;
1154aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = vt_setmode(pvc, pmode);
1155aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1156aecfc01dSrui zang - Sun Microsystems - Beijing China 
1157aecfc01dSrui zang - Sun Microsystems - Beijing China 	case KDGETMODE:
1158aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_OPENQRY:
1159aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETMODE:
1160aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETDISPINFO:
1161aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETSTATE:
1162aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_ENABLED:
1163aecfc01dSrui zang - Sun Microsystems - Beijing China 	case VT_GETACTIVE:
1164aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1165aecfc01dSrui zang - Sun Microsystems - Beijing China 
1166aecfc01dSrui zang - Sun Microsystems - Beijing China 	default:
1167aecfc01dSrui zang - Sun Microsystems - Beijing China 		error = ENXIO;
1168aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1169aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1170aecfc01dSrui zang - Sun Microsystems - Beijing China 
1171aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (error != 0)
1172aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocnak(qp, mp, error);
1173aecfc01dSrui zang - Sun Microsystems - Beijing China 	else
1174aecfc01dSrui zang - Sun Microsystems - Beijing China 		vt_iocack(qp, mp);
1175aecfc01dSrui zang - Sun Microsystems - Beijing China }
1176aecfc01dSrui zang - Sun Microsystems - Beijing China 
1177aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_iocack(queue_t * qp,mblk_t * mp)1178aecfc01dSrui zang - Sun Microsystems - Beijing China vt_iocack(queue_t *qp, mblk_t *mp)
1179aecfc01dSrui zang - Sun Microsystems - Beijing China {
1180aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct iocblk	*iocbp = (struct iocblk *)(void *)mp->b_rptr;
1181aecfc01dSrui zang - Sun Microsystems - Beijing China 
1182aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_datap->db_type = M_IOCACK;
1183aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_wptr = mp->b_rptr + sizeof (struct iocblk);
1184aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocbp->ioc_error = 0;
1185aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocbp->ioc_count = 0;
1186aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocbp->ioc_rval = 0;
1187aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (mp->b_cont != NULL) {
1188aecfc01dSrui zang - Sun Microsystems - Beijing China 		freemsg(mp->b_cont);
1189aecfc01dSrui zang - Sun Microsystems - Beijing China 		mp->b_cont = NULL;
1190aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1191aecfc01dSrui zang - Sun Microsystems - Beijing China 	qreply(qp, mp);
1192aecfc01dSrui zang - Sun Microsystems - Beijing China }
1193aecfc01dSrui zang - Sun Microsystems - Beijing China 
1194aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_iocnak(queue_t * qp,mblk_t * mp,int error)1195aecfc01dSrui zang - Sun Microsystems - Beijing China vt_iocnak(queue_t *qp, mblk_t *mp, int error)
1196aecfc01dSrui zang - Sun Microsystems - Beijing China {
1197aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct iocblk *iocp = (struct iocblk *)(void *)mp->b_rptr;
1198aecfc01dSrui zang - Sun Microsystems - Beijing China 
1199aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_datap->db_type = M_IOCNAK;
1200aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocp->ioc_rval = 0;
1201aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocp->ioc_count = 0;
1202aecfc01dSrui zang - Sun Microsystems - Beijing China 	iocp->ioc_error = error;
1203aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (mp->b_cont != NULL) {
1204aecfc01dSrui zang - Sun Microsystems - Beijing China 		freemsg(mp->b_cont);
1205aecfc01dSrui zang - Sun Microsystems - Beijing China 		mp->b_cont = NULL;
1206aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1207aecfc01dSrui zang - Sun Microsystems - Beijing China 	qreply(qp, mp);
1208aecfc01dSrui zang - Sun Microsystems - Beijing China }
1209aecfc01dSrui zang - Sun Microsystems - Beijing China 
1210aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_copyin(queue_t * qp,mblk_t * mp,uint_t size)1211aecfc01dSrui zang - Sun Microsystems - Beijing China vt_copyin(queue_t *qp, mblk_t *mp, uint_t size)
1212aecfc01dSrui zang - Sun Microsystems - Beijing China {
1213aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct copyreq  *cqp;
1214aecfc01dSrui zang - Sun Microsystems - Beijing China 
1215aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp = (struct copyreq *)(void *)mp->b_rptr;
1216aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_addr = *((caddr_t *)(void *)mp->b_cont->b_rptr);
1217aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_size = size;
1218aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_flag = 0;
1219aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_private = (mblk_t *)NULL;
1220aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_wptr = mp->b_rptr + sizeof (struct copyreq);
1221aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_datap->db_type = M_COPYIN;
1222aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (mp->b_cont)
1223aecfc01dSrui zang - Sun Microsystems - Beijing China 		freemsg(mp->b_cont);
1224aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_cont = (mblk_t *)NULL;
1225aecfc01dSrui zang - Sun Microsystems - Beijing China 	qreply(qp, mp);
1226aecfc01dSrui zang - Sun Microsystems - Beijing China }
1227aecfc01dSrui zang - Sun Microsystems - Beijing China 
1228aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_copyout(queue_t * qp,mblk_t * mp,mblk_t * tmp,uint_t size)1229aecfc01dSrui zang - Sun Microsystems - Beijing China vt_copyout(queue_t *qp, mblk_t *mp, mblk_t *tmp, uint_t size)
1230aecfc01dSrui zang - Sun Microsystems - Beijing China {
1231aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct copyreq  *cqp;
1232aecfc01dSrui zang - Sun Microsystems - Beijing China 
1233aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp = (struct copyreq *)(void *)mp->b_rptr;
1234aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_size = size;
1235aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_addr = *((caddr_t *)(void *)mp->b_cont->b_rptr);
1236aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_flag = 0;
1237aecfc01dSrui zang - Sun Microsystems - Beijing China 	cqp->cq_private = (mblk_t *)NULL;
1238aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_wptr = mp->b_rptr + sizeof (struct copyreq);
1239aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_datap->db_type = M_COPYOUT;
1240aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (mp->b_cont)
1241aecfc01dSrui zang - Sun Microsystems - Beijing China 		freemsg(mp->b_cont);
1242aecfc01dSrui zang - Sun Microsystems - Beijing China 	mp->b_cont = tmp;
1243aecfc01dSrui zang - Sun Microsystems - Beijing China 	qreply(qp, mp);
1244aecfc01dSrui zang - Sun Microsystems - Beijing China }
1245aecfc01dSrui zang - Sun Microsystems - Beijing China 
1246aecfc01dSrui zang - Sun Microsystems - Beijing China /*
1247aecfc01dSrui zang - Sun Microsystems - Beijing China  * Get vc state from minor.
1248aecfc01dSrui zang - Sun Microsystems - Beijing China  * Once a caller gets a vc_state_t from this function,
1249aecfc01dSrui zang - Sun Microsystems - Beijing China  * the vc_state_t is guaranteed not being freed before
1250aecfc01dSrui zang - Sun Microsystems - Beijing China  * the caller leaves this STREAMS module by the D_MTPERMOD
1251aecfc01dSrui zang - Sun Microsystems - Beijing China  * perimeter.
1252aecfc01dSrui zang - Sun Microsystems - Beijing China  */
1253aecfc01dSrui zang - Sun Microsystems - Beijing China vc_state_t *
vt_minor2vc(minor_t minor)1254aecfc01dSrui zang - Sun Microsystems - Beijing China vt_minor2vc(minor_t minor)
1255aecfc01dSrui zang - Sun Microsystems - Beijing China {
1256aecfc01dSrui zang - Sun Microsystems - Beijing China 	avl_index_t where;
1257aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_state_t target;
1258aecfc01dSrui zang - Sun Microsystems - Beijing China 
1259aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (minor != VT_ACTIVE) {
1260aecfc01dSrui zang - Sun Microsystems - Beijing China 		target.vc_minor = minor;
1261aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (avl_find(&vc_avl_root, &target, &where));
1262aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1263aecfc01dSrui zang - Sun Microsystems - Beijing China 
1264aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (vc_active_console == VT_MINOR_INVALID)
1265aecfc01dSrui zang - Sun Microsystems - Beijing China 		target.vc_minor = 0;
1266aecfc01dSrui zang - Sun Microsystems - Beijing China 	else
1267aecfc01dSrui zang - Sun Microsystems - Beijing China 		target.vc_minor = vc_active_console;
1268aecfc01dSrui zang - Sun Microsystems - Beijing China 
1269aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (avl_find(&vc_avl_root, &target, &where));
1270aecfc01dSrui zang - Sun Microsystems - Beijing China }
1271aecfc01dSrui zang - Sun Microsystems - Beijing China 
1272aecfc01dSrui zang - Sun Microsystems - Beijing China static void
vt_state_init(vc_state_t * vcptr,minor_t minor)1273aecfc01dSrui zang - Sun Microsystems - Beijing China vt_state_init(vc_state_t *vcptr, minor_t minor)
1274aecfc01dSrui zang - Sun Microsystems - Beijing China {
1275aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_init(&vcptr->vc_state_lock, NULL, MUTEX_DRIVER, NULL);
1276aecfc01dSrui zang - Sun Microsystems - Beijing China 
1277aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&vcptr->vc_state_lock);
1278aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_flags = 0;
1279aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&vcptr->vc_state_lock);
1280aecfc01dSrui zang - Sun Microsystems - Beijing China 
1281aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_pid = -1;
1282aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_dispnum = 0;
1283aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_login = 0;
1284aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_switchto = VT_MINOR_INVALID;
1285aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_switch_mode = VT_AUTO;
1286aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_relsig = SIGUSR1;
1287aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_acqsig = SIGUSR1;
1288aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_tem = NULL;
1289aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_bufcallid = 0;
1290aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_timeoutid = 0;
1291aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_wq = NULL;
1292aecfc01dSrui zang - Sun Microsystems - Beijing China 	vcptr->vc_minor = minor;
1293aecfc01dSrui zang - Sun Microsystems - Beijing China }
1294aecfc01dSrui zang - Sun Microsystems - Beijing China 
1295aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_resize(uint_t count)1296aecfc01dSrui zang - Sun Microsystems - Beijing China vt_resize(uint_t count)
1297aecfc01dSrui zang - Sun Microsystems - Beijing China {
1298aecfc01dSrui zang - Sun Microsystems - Beijing China 	uint_t vc_num, i;
1299aecfc01dSrui zang - Sun Microsystems - Beijing China 
1300aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(MUTEX_HELD(&vc_lock));
1301aecfc01dSrui zang - Sun Microsystems - Beijing China 
1302aecfc01dSrui zang - Sun Microsystems - Beijing China 	vc_num = VC_INSTANCES_COUNT;
1303aecfc01dSrui zang - Sun Microsystems - Beijing China 
1304aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count == vc_num)
1305aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1306aecfc01dSrui zang - Sun Microsystems - Beijing China 
1307aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count > vc_num) {
1308aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (i = vc_num; i < count; i++) {
1309aecfc01dSrui zang - Sun Microsystems - Beijing China 			vc_state_t *vcptr = kmem_zalloc(sizeof (vc_state_t),
1310aecfc01dSrui zang - Sun Microsystems - Beijing China 			    KM_SLEEP);
1311aecfc01dSrui zang - Sun Microsystems - Beijing China 			vt_state_init(vcptr, i);
1312aecfc01dSrui zang - Sun Microsystems - Beijing China 			avl_add(&vc_avl_root, vcptr);
1313aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1314aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1315aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1316aecfc01dSrui zang - Sun Microsystems - Beijing China 
1317aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = vc_num; i > count; i--) {
1318aecfc01dSrui zang - Sun Microsystems - Beijing China 		avl_index_t where;
1319aecfc01dSrui zang - Sun Microsystems - Beijing China 		vc_state_t target, *found;
1320aecfc01dSrui zang - Sun Microsystems - Beijing China 
1321aecfc01dSrui zang - Sun Microsystems - Beijing China 		target.vc_minor = i - 1;
1322aecfc01dSrui zang - Sun Microsystems - Beijing China 		found = avl_find(&vc_avl_root, &target, &where);
1323aecfc01dSrui zang - Sun Microsystems - Beijing China 		ASSERT(found != NULL && found->vc_flags == 0);
1324aecfc01dSrui zang - Sun Microsystems - Beijing China 		avl_remove(&vc_avl_root, found);
1325aecfc01dSrui zang - Sun Microsystems - Beijing China 		kmem_free(found, sizeof (vc_state_t));
1326aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1327aecfc01dSrui zang - Sun Microsystems - Beijing China }
1328aecfc01dSrui zang - Sun Microsystems - Beijing China 
1329aecfc01dSrui zang - Sun Microsystems - Beijing China static int
vc_avl_compare(const void * first,const void * second)1330aecfc01dSrui zang - Sun Microsystems - Beijing China vc_avl_compare(const void *first, const void *second)
1331aecfc01dSrui zang - Sun Microsystems - Beijing China {
1332aecfc01dSrui zang - Sun Microsystems - Beijing China 	const vc_state_t *vcptr1 = first;
1333aecfc01dSrui zang - Sun Microsystems - Beijing China 	const vc_state_t *vcptr2 = second;
1334aecfc01dSrui zang - Sun Microsystems - Beijing China 
1335aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (vcptr1->vc_minor < vcptr2->vc_minor)
1336aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (-1);
1337aecfc01dSrui zang - Sun Microsystems - Beijing China 
1338aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (vcptr1->vc_minor == vcptr2->vc_minor)
1339aecfc01dSrui zang - Sun Microsystems - Beijing China 		return (0);
1340aecfc01dSrui zang - Sun Microsystems - Beijing China 
1341aecfc01dSrui zang - Sun Microsystems - Beijing China 	return (1);
1342aecfc01dSrui zang - Sun Microsystems - Beijing China }
1343aecfc01dSrui zang - Sun Microsystems - Beijing China 
1344aecfc01dSrui zang - Sun Microsystems - Beijing China /*
1345aecfc01dSrui zang - Sun Microsystems - Beijing China  * Only called from wc init().
1346aecfc01dSrui zang - Sun Microsystems - Beijing China  */
1347aecfc01dSrui zang - Sun Microsystems - Beijing China void
vt_init(void)1348aecfc01dSrui zang - Sun Microsystems - Beijing China vt_init(void)
1349aecfc01dSrui zang - Sun Microsystems - Beijing China {
1350aecfc01dSrui zang - Sun Microsystems - Beijing China #ifdef	__lock_lint
1351aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(NO_COMPETING_THREADS);
1352aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
1353aecfc01dSrui zang - Sun Microsystems - Beijing China 
1354aecfc01dSrui zang - Sun Microsystems - Beijing China 	avl_create(&vc_avl_root, vc_avl_compare, sizeof (vc_state_t),
1355aecfc01dSrui zang - Sun Microsystems - Beijing China 	    offsetof(vc_state_t, vc_avl_node));
1356aecfc01dSrui zang - Sun Microsystems - Beijing China 
1357aecfc01dSrui zang - Sun Microsystems - Beijing China 	list_create(&vc_waitactive_list, sizeof (vc_waitactive_msg_t),
1358aecfc01dSrui zang - Sun Microsystems - Beijing China 	    offsetof(vc_waitactive_msg_t, wa_list_node));
1359aecfc01dSrui zang - Sun Microsystems - Beijing China 
1360aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_init(&vc_lock, NULL, MUTEX_DRIVER, NULL);
1361aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_init(&vt_pending_vtno_lock, NULL, MUTEX_DRIVER, NULL);
1362aecfc01dSrui zang - Sun Microsystems - Beijing China }
1363