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