xref: /illumos-gate/usr/src/uts/common/io/conskbd.c (revision 4bc0a2ef)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Console kbd multiplexor driver for Sun.
31  * The console "zs" port is linked under us, with the "kbd" module pushed
32  * on top of it.
33  * Minor device 0 is what programs normally use.
34  * Minor device 1 is used to feed predigested keystrokes to the "workstation
35  * console" driver, which it is linked beneath.
36  *
37  *
38  *     This module can support multiple keyboards to be used simultaneously.
39  * and enable users to use at a time multiple keyboards connected to the
40  * same system. All the keyboards are linked under conskbd, and act as a
41  * keyboard with replicated keys.
42  *
43  *     The DIN keyboards of SUN, for exmple , type 3/4/5,  are supported via
44  * a two-level architecure. The lower one is one of serialport drivers, such
45  * as zs, se, and the upper is  "kb" STREAMS module. Currenly, the serialport
46  * drivers don't support polled I/O interfaces, we couldn't group the keyboard
47  * of this kind under conskbd. So we do as the follows:
48  *
49  *         A new ioctl CONSSETKBDTYPE interface between conskbd and lower
50  *     keyboard drivers is added. When conskbd receives I_LINK or I_PLINK
51  *     ioctl, it will send a CONSSETKBDTYPE ioctl to the driver which is
52  *     requesting to be linked under conskbd. If the lower driver does't
53  *     recognize this ioctl, the virtual keyboard will be disabled so that
54  *     only one keyboard instance could be linked under conskbd.
55  */
56 #define	KEYMAP_SIZE_VARIABLE
57 
58 #include <sys/types.h>
59 #include <sys/param.h>
60 #include <sys/stropts.h>
61 #include <sys/stream.h>
62 #include <sys/strsubr.h>
63 #include <sys/strsun.h>
64 #include <sys/conf.h>
65 #include <sys/stat.h>
66 #include <sys/errno.h>
67 #include <sys/modctl.h>
68 #include <sys/kbio.h>
69 #include <sys/ddi.h>
70 #include <sys/sunddi.h>
71 #include <sys/consdev.h>
72 #include <sys/note.h>
73 #include <sys/kmem.h>
74 #include <sys/kstat.h>
75 #include <sys/policy.h>
76 #include <sys/kbd.h>
77 #include <sys/kbtrans.h>
78 #include <sys/promif.h>
79 #include <sys/vuid_event.h>
80 #include <sys/conskbd.h>
81 
82 extern struct keyboard *kbtrans_usbkb_maptab_init(void);
83 extern void kbtrans_usbkb_maptab_fini(struct keyboard **);
84 extern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t);
85 
86 /*
87  * Module linkage routines for the kernel
88  */
89 static int conskbd_attach(dev_info_t *, ddi_attach_cmd_t);
90 static int conskbd_detach(dev_info_t *, ddi_detach_cmd_t);
91 static int conskbd_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
92 
93 /*
94  * STREAMS queue processing procedures
95  */
96 static void	conskbduwsrv(queue_t *);
97 static void	conskbdlwserv(queue_t *);
98 static void	conskbdlrput(queue_t *, mblk_t *);
99 static void	conskbdioctl(queue_t *, mblk_t *);
100 static int	conskbdclose(queue_t *, int, cred_t *);
101 static int	conskbdopen(queue_t *, dev_t *, int, int, cred_t *);
102 
103 
104 /* STREAMS driver id and limit value struct */
105 static struct module_info conskbdm_info = {
106 	0,		/* mi_idnum */
107 	"conskbd",	/* mi_idname */
108 	0,		/* mi_minpsz */
109 	1024,		/* mi_maxpsz */
110 	2048,		/* mi_hiwat */
111 	128		/* mi_lowat */
112 };
113 
114 /*
115  * STREAMS queue processing procedure structures
116  */
117 /* upper read queue processing procedure structures */
118 static struct qinit conskbdurinit = {
119 	NULL,			/* qi_putp */
120 	(int (*)())NULL,	/* qi_srvp */
121 	conskbdopen,		/* qi_qopen */
122 	conskbdclose,		/* qi_qclose */
123 	(int (*)())NULL,	/* qi_qadmin */
124 	&conskbdm_info,		/* qi_minfo */
125 	NULL			/* qi_mstat */
126 };
127 
128 /* upper write queue processing procedures structuresi */
129 static struct qinit conskbduwinit = {
130 	(int (*)())putq,		/* qi_putp */
131 	(int (*)())conskbduwsrv,	/* qi_srvp */
132 	conskbdopen,			/* qi_qopen */
133 	conskbdclose,			/* qi_qclose */
134 	(int (*)())NULL,		/* qi_qadmin */
135 	&conskbdm_info,			/* qi_minfo */
136 	NULL				/* qi_mstat */
137 };
138 
139 /* lower read queue processing procedures structures */
140 static struct qinit conskbdlrinit = {
141 	(int (*)())conskbdlrput,	/* qi_putp */
142 	(int (*)())NULL,		/* qi_srvp */
143 	(int (*)())NULL,		/* qi_qopen */
144 	(int (*)())NULL,		/* qi_qclose */
145 	(int (*)())NULL,		/* qi_qadmin */
146 	&conskbdm_info,			/* qi_minfo */
147 	NULL				/* qi_mstat */
148 };
149 
150 /* lower write processing procedures structures */
151 static struct qinit conskbdlwinit = {
152 	putq,				/* qi_putp */
153 	(int (*)())conskbdlwserv,	/* qi_srvp */
154 	(int (*)())NULL,		/* qi_qopen */
155 	(int (*)())NULL,		/* qi_qclose */
156 	(int (*)())NULL,		/* qi_qadmin */
157 	&conskbdm_info,			/* qi_minfo */
158 	NULL				/* qi_mstat */
159 };
160 
161 /* STREAMS entity declaration structure */
162 static struct streamtab conskbd_str_info = {
163 	&conskbdurinit,		/* st_rdinit */
164 	&conskbduwinit,		/* st_wrinit */
165 	&conskbdlrinit,		/* st_muxrinit */
166 	&conskbdlwinit,		/* st_muxwinit */
167 };
168 
169 
170 /* Entry points structure */
171 static 	struct cb_ops cb_conskbd_ops = {
172 	nulldev,		/* cb_open */
173 	nulldev,		/* cb_close */
174 	nodev,			/* cb_strategy */
175 	nodev,			/* cb_print */
176 	nodev,			/* cb_dump */
177 	nodev,			/* cb_read */
178 	nodev,			/* cb_write */
179 	nodev,			/* cb_ioctl */
180 	nodev,			/* cb_devmap */
181 	nodev,			/* cb_mmap */
182 	nodev,			/* cb_segmap */
183 	nochpoll,		/* cb_chpoll */
184 	ddi_prop_op,		/* cb_prop_op */
185 	&conskbd_str_info,	/* cb_stream */
186 	D_MP | D_MTOUTPERIM	/* cb_flag */
187 };
188 
189 
190 /*
191  * Device operations structure
192  */
193 static struct dev_ops conskbd_ops = {
194 	DEVO_REV,		/* devo_rev */
195 	0,			/* devo_refcnt */
196 	conskbd_info,		/* devo_getinfo */
197 	nulldev,		/* devo_identify */
198 	nulldev,		/* devo_probe */
199 	conskbd_attach,		/* devo_attach */
200 	conskbd_detach,		/* devo_detach */
201 	nodev,			/* devo_reset */
202 	&(cb_conskbd_ops),	/* devo_cb_ops */
203 	(struct bus_ops *)NULL,	/* devo_bus_ops */
204 	NULL			/* devo_power */
205 };
206 
207 /*
208  * Module linkage information for the kernel.
209  */
210 static struct modldrv modldrv = {
211 	&mod_driverops, /* Type of module.  This one is a pseudo driver */
212 	"Console kbd Multiplexer driver 'conskbd' %I%",
213 	&conskbd_ops,	/* driver ops */
214 };
215 
216 /*
217  * Module linkage structure
218  */
219 static struct modlinkage modlinkage = {
220 	MODREV_1,	/* ml_rev */
221 	&modldrv,	/* ml_linkage */
222 	NULL		/* NULL terminates the list */
223 };
224 
225 /*
226  * Debug printing
227  */
228 #ifndef DPRINTF
229 #ifdef DEBUG
230 void	conskbd_dprintf(const char *fmt, ...);
231 #define	DPRINTF(l, m, args) \
232 	(((l) >= conskbd_errlevel) && ((m) & conskbd_errmask) ?	\
233 		conskbd_dprintf args :				\
234 		(void) 0)
235 
236 /*
237  * Severity levels for printing
238  */
239 #define	PRINT_L0	0	/* print every message */
240 #define	PRINT_L1	1	/* debug */
241 #define	PRINT_L2	2	/* quiet */
242 
243 /*
244  * Masks
245  */
246 #define	PRINT_MASK_ALL		0xFFFFFFFFU
247 uint_t	conskbd_errmask = PRINT_MASK_ALL;
248 uint_t	conskbd_errlevel = PRINT_L2;
249 
250 #else
251 #define	DPRINTF(l, m, args)	/* NOTHING */
252 #endif
253 #endif
254 
255 /*
256  * Module global data are protected by the per-module inner perimeter
257  */
258 static	queue_t	*conskbd_regqueue; /* regular keyboard queue above us */
259 static	queue_t	*conskbd_consqueue; /* console queue above us */
260 
261 
262 static dev_info_t *conskbd_dip;		/* private copy of devinfo pointer */
263 static long	conskbd_idle_stamp;	/* seconds tstamp of latest keystroke */
264 static struct keyboard *conskbd_keyindex;
265 
266 /*
267  * Normally, kstats of type KSTAT_TYPE_NAMED have multiple elements.  In
268  * this case we use this type for a single element because the ioctl code
269  * for it knows how to handle mixed kernel/user data models.  Also, it
270  * will be easier to add new statistics later.
271  */
272 static struct {
273 	kstat_named_t idle_sec;		/* seconds since last keystroke */
274 } conskbd_kstat = {
275 	{ "idle_sec", KSTAT_DATA_LONG, }
276 };
277 
278 /*
279  * Local routines prototypes
280  */
281 static int conskbd_kstat_update(kstat_t *, int);
282 
283 static void conskbd_ioc_plink(queue_t *, mblk_t *);
284 static void conskbd_legacy_kbd_ioctl(queue_t *, mblk_t *);
285 static void conskbd_virtual_kbd_ioctl(queue_t *, mblk_t *);
286 
287 static conskbd_pending_msg_t *conskbd_mux_find_msg(mblk_t *);
288 static void conskbd_mux_enqueue_msg(conskbd_pending_msg_t *);
289 static void conskbd_mux_dequeue_msg(conskbd_pending_msg_t *);
290 static void conskbd_link_lower_queue(conskbd_lower_queue_t *);
291 
292 static void conskbd_handle_downstream_msg(queue_t *, mblk_t *);
293 static void conskbd_kioctype_complete(conskbd_lower_queue_t *, mblk_t *);
294 static void conskbd_kioctrans_complete(conskbd_lower_queue_t *, mblk_t *);
295 static void conskbd_kioclayout_complete(conskbd_lower_queue_t *, mblk_t *);
296 static void conskbd_kiocsled_complete(conskbd_lower_queue_t *, mblk_t *);
297 static void conskbd_mux_upstream_msg(conskbd_lower_queue_t *, mblk_t *);
298 static void conskbd_legacy_upstream_msg(conskbd_lower_queue_t *, mblk_t *);
299 static void conskbd_lqs_ack_complete(conskbd_lower_queue_t *, mblk_t *);
300 
301 static void conskbd_polledio_enter(struct cons_polledio_arg *);
302 static void conskbd_polledio_exit(struct cons_polledio_arg *);
303 static int  conskbd_polledio_ischar(struct cons_polledio_arg *);
304 static int  conskbd_polledio_getchar(struct cons_polledio_arg *);
305 static void conskbd_polledio_setled(struct kbtrans_hardware *, int);
306 
307 static void conskbd_streams_setled(struct kbtrans_hardware *, int);
308 static boolean_t conskbd_override_kbtrans(queue_t *, mblk_t *);
309 static boolean_t
310 conskbd_polled_keycheck(struct kbtrans_hardware *,
311 		kbtrans_key_t *, enum keystate *);
312 
313 /*
314  * Callbacks needed by kbtrans
315  */
316 static struct kbtrans_callbacks conskbd_callbacks = {
317 	conskbd_streams_setled,
318 	conskbd_polledio_setled,
319 	conskbd_polled_keycheck,
320 };
321 
322 /*
323  * Single private "global" lock for the few rare conditions
324  * we want single-threaded.
325  */
326 static	kmutex_t	conskbd_lq_lock;
327 static	kmutex_t	conskbd_msgq_lock;
328 static	conskbd_pending_msg_t	*conskbd_msg_queue;
329 
330 /*
331  * The software state structure of virtual keyboard.
332  * Currently, only one virtual keyboard is support.
333  */
334 static conskbd_state_t	conskbd = { 0 };
335 
336 /*
337  * _init()
338  *
339  * Description:
340  *      Driver initialization, called when driver is first loaded.
341  *      This is how access is initially given to all the static structures.
342  *
343  * Arguments:
344  *      None
345  *
346  * Returns:
347  *      ddi_soft_state_init() status, see ddi_soft_state_init(9f), or
348  *      mod_install() status, see mod_install(9f)
349  */
350 int
351 _init(void)
352 {
353 	int	error;
354 
355 	error = mod_install(&modlinkage);
356 	if (error != 0) {
357 		return (error);
358 	}
359 
360 	conskbd_keyindex = kbtrans_usbkb_maptab_init();
361 
362 	mutex_init(&conskbd_lq_lock, NULL, MUTEX_DRIVER, NULL);
363 	mutex_init(&conskbd_msgq_lock, NULL, MUTEX_DRIVER, NULL);
364 
365 	return (error);
366 
367 }	/* _init() */
368 
369 /*
370  * _fini()
371  *
372  * Description:
373  *      Module de-initialization, called when the driver is to be unloaded.
374  *
375  * Arguments:
376  *      None
377  *
378  * Returns:
379  *      mod_remove() status, see mod_remove(9f)
380  */
381 int
382 _fini(void)
383 {
384 	int	error;
385 
386 	error = mod_remove(&modlinkage);
387 	if (error != 0)
388 		return (error);
389 	mutex_destroy(&conskbd_lq_lock);
390 	mutex_destroy(&conskbd_msgq_lock);
391 	kbtrans_usbkb_maptab_fini(&conskbd_keyindex);
392 
393 	return (0);
394 
395 }	/* _fini() */
396 
397 /*
398  * _info()
399  *
400  * Description:
401  *      Module information, returns information about the driver.
402  *
403  * Arguments:
404  *      modinfo         *modinfop       Pointer to the opaque modinfo structure
405  *
406  * Returns:
407  *      mod_info() status, see mod_info(9f)
408  */
409 int
410 _info(struct modinfo *modinfop)
411 {
412 	return (mod_info(&modlinkage, modinfop));
413 
414 }	/* _info() */
415 
416 
417 /*
418  * conskbd_attach()
419  *
420  * Description:
421  * 	This routine creates two device nodes. One is the "kbd" node, which
422  * is used by user application programs(such as Xserver).The other is the
423  * "conskbd" node, which is an internal node. consconfig_dacf module will
424  * open this internal node, and link the conskbd under the wc (workstaion
425  * console).
426  *
427  * Arguments:
428  *      dev_info_t      *dip    Pointer to the device's dev_info struct
429  *      ddi_attach_cmd_t cmd    Attach command
430  *
431  * Returns:
432  *      DDI_SUCCESS             The driver was initialized properly
433  *      DDI_FAILURE             The driver couldn't be initialized properly
434  */
435 /*ARGSUSED*/
436 static int
437 conskbd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
438 {
439 	kstat_t	*ksp;
440 
441 	switch (cmd) {
442 	case DDI_ATTACH:
443 		break;
444 
445 	default:
446 		return (DDI_FAILURE);
447 
448 	}
449 	if ((ddi_create_minor_node(devi, "kbd", S_IFCHR,
450 	    0, DDI_PSEUDO, NULL) == DDI_FAILURE) ||
451 	    (ddi_create_internal_pathname(devi, "conskbd", S_IFCHR,
452 	    1) == DDI_FAILURE)) {
453 		ddi_remove_minor_node(devi, NULL);
454 		return (DDI_FAILURE);
455 	}
456 	conskbd_dip = devi;
457 
458 	ksp = kstat_create("conskbd", 0, "activity", "misc", KSTAT_TYPE_NAMED,
459 	    sizeof (conskbd_kstat) / sizeof (kstat_named_t),
460 	    KSTAT_FLAG_VIRTUAL);
461 	if (ksp) {
462 		ksp->ks_data = (void *) &conskbd_kstat;
463 		ksp->ks_update = conskbd_kstat_update;
464 		kstat_install(ksp);
465 		conskbd_idle_stamp = gethrestime_sec();	/* initial value */
466 	}
467 
468 	conskbd.conskbd_layout = -1;	/* invalid layout */
469 	conskbd.conskbd_led_state = -1;
470 	conskbd.conskbd_bypassed = B_FALSE;
471 
472 	return (DDI_SUCCESS);
473 
474 }	/* conskbd_attach() */
475 
476 /*
477  * conskbd_detach()
478  *
479  * Description:
480  *      Detach an instance of the conskbd driver. In fact, the driver can not
481  * be detached.
482  *
483  * Arguments:
484  *      dev_info_t              *dip    Pointer to the device's dev_info struct
485  *      ddi_detach_cmd_t        cmd     Detach command
486  *
487  * Returns:
488  *      DDI_SUCCESS     The driver was detached
489  *      DDI_FAILURE     The driver couldn't be detached
490  */
491 /*ARGSUSED*/
492 static int
493 conskbd_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
494 {
495 	return (DDI_FAILURE);
496 
497 }	/* conskbd_detach() */
498 
499 /* ARGSUSED */
500 static int
501 conskbd_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
502 	void **result)
503 {
504 	register int error;
505 
506 	switch (infocmd) {
507 	case DDI_INFO_DEVT2DEVINFO:
508 		if (conskbd_dip == NULL) {
509 			error = DDI_FAILURE;
510 		} else {
511 			*result = (void *) conskbd_dip;
512 			error = DDI_SUCCESS;
513 		}
514 		break;
515 	case DDI_INFO_DEVT2INSTANCE:
516 		*result = (void *)0;
517 		error = DDI_SUCCESS;
518 		break;
519 	default:
520 		error = DDI_FAILURE;
521 	}
522 	return (error);
523 
524 }	/* conskbd_info() */
525 
526 /*ARGSUSED*/
527 static int
528 conskbdopen(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp)
529 {
530 	dev_t	unit;
531 	int	err;
532 
533 	unit = getminor(*devp);
534 
535 	if (unit == 0) {
536 		/*
537 		 * Opening "/dev/kbd".
538 		 */
539 		conskbd_regqueue = q;
540 		qprocson(q);
541 		return (0);
542 	} else if (unit != 1) {
543 		/* we don't do that under Bozo's Big Tent */
544 		return (ENODEV);
545 	}
546 
547 	/*
548 	 * Opening the device to be linked under the console.
549 	 */
550 	conskbd_consqueue = q;
551 
552 	/*
553 	 * initialzie kbtrans module for conskbd
554 	 */
555 	err = kbtrans_streams_init(q, sflag, crp, (struct kbtrans_hardware *)
556 	    &conskbd, &conskbd_callbacks, &conskbd.conskbd_kbtrans, 0, 0);
557 	if (err != 0)
558 		return (err);
559 	kbtrans_streams_set_keyboard(conskbd.conskbd_kbtrans, KB_USB,
560 	    conskbd_keyindex);
561 
562 	conskbd.conskbd_polledio.cons_polledio_version = CONSPOLLEDIO_V1;
563 	conskbd.conskbd_polledio.cons_polledio_argument =
564 	    (struct cons_polledio_arg *)&conskbd;
565 	conskbd.conskbd_polledio.cons_polledio_putchar = NULL;
566 	conskbd.conskbd_polledio.cons_polledio_getchar =
567 	    (int (*)(struct cons_polledio_arg *)) conskbd_polledio_getchar;
568 	conskbd.conskbd_polledio.cons_polledio_ischar =
569 	    (boolean_t (*)(struct cons_polledio_arg *))conskbd_polledio_ischar;
570 	conskbd.conskbd_polledio.cons_polledio_enter = conskbd_polledio_enter;
571 	conskbd.conskbd_polledio.cons_polledio_exit = conskbd_polledio_exit;
572 	qprocson(q);
573 	kbtrans_streams_enable(conskbd.conskbd_kbtrans);
574 
575 	return (0);
576 
577 }	/* conskbd_open() */
578 
579 
580 /*ARGSUSED*/
581 static int
582 conskbdclose(queue_t *q, int flag, cred_t *crp)
583 {
584 	if (q == conskbd_regqueue) {
585 
586 		/* switch the input stream back to conskbd_consqueue */
587 		conskbd.conskbd_directio = B_FALSE;
588 
589 		kbtrans_streams_untimeout(conskbd.conskbd_kbtrans);
590 		kbtrans_streams_set_queue(conskbd.conskbd_kbtrans,
591 		    conskbd_consqueue);
592 		qprocsoff(q);
593 		conskbd_regqueue = NULL;
594 	} else if (q == conskbd_consqueue) {
595 		/*
596 		 * Well, this is probably a mistake, but we will permit you
597 		 * to close the path to the console if you really insist.
598 		 */
599 		qprocsoff(q);
600 		conskbd_consqueue = NULL;
601 	}
602 
603 	return (0);
604 
605 }	/* conskbd_close() */
606 
607 /*
608  * Service procedure for upper write queue.
609  *	To make sure the order of messages, we don't process any
610  * message in qi_putq() routine of upper write queue, instead the
611  * qi_putq() routine, which is a standard putq() routine, puts all
612  * messages into a queue, and lets the following service procedure
613  * deal with all messages.
614  * 	This routine is invoked when ioctl commands are send down
615  * by a consumer of the keyboard device, eg, when the keyboard
616  * consumer tries to determine the keyboard layout type, or sets
617  * the led states.
618  */
619 static void
620 conskbduwsrv(queue_t *q)
621 {
622 	mblk_t	*mp;
623 	queue_t	*oldq;
624 	enum kbtrans_message_response ret;
625 
626 	while ((mp = getq(q)) != NULL) {
627 
628 		/*
629 		 * if the virtual keyboard is supported
630 		 */
631 		if (conskbd.conskbd_bypassed == B_FALSE) {
632 
633 			if (conskbd_override_kbtrans(q, mp) == B_TRUE)
634 				continue;
635 			/*
636 			 * The conskbd driver is a psaudo driver. It has two
637 			 * devcice nodes, one is used by kernel, and the other
638 			 * is used by end-users. There are two STREAMS queues
639 			 * corresponding to the two device nodes, console queue
640 			 * and regular queue.
641 			 * In conskbd_override_kbtrans() routine, when receives
642 			 * KIOCSDIRECT ioctl, we need change the direction of
643 			 * keyboard input messages, and direct the input stream
644 			 * from keyboard into right queue. It causes this queue
645 			 * to be switched between regular queue and console
646 			 * queue. And here, in this routine, the in-parameter
647 			 * "q" can be any one of the two. Moreover, this module
648 			 * is executed in multithreaded environment, even if the
649 			 * q is switched to regular queue, it is possible that
650 			 * the in-parameter is still the console queue, and we
651 			 * need to return response to right queue.
652 			 * The response is sent to upstream by the kbtrans
653 			 * module. so we need to save the old queue, and wait
654 			 * kbtrans to proces message and to send response out,
655 			 * and then switch back to old queue.
656 			 */
657 			oldq = kbtrans_streams_get_queue(
658 			    conskbd.conskbd_kbtrans);
659 			kbtrans_streams_set_queue(
660 			    conskbd.conskbd_kbtrans, RD(q));
661 			ret = kbtrans_streams_message(
662 			    conskbd.conskbd_kbtrans, mp);
663 			kbtrans_streams_set_queue(
664 			    conskbd.conskbd_kbtrans, oldq);
665 
666 			switch (ret) {
667 				case KBTRANS_MESSAGE_HANDLED:
668 					continue;
669 				case KBTRANS_MESSAGE_NOT_HANDLED:
670 					break;
671 			}
672 		}
673 
674 		switch (mp->b_datap->db_type) {
675 
676 		case M_IOCTL:
677 			conskbdioctl(q, mp);
678 			break;
679 
680 		case M_FLUSH:
681 			if (*mp->b_rptr & FLUSHW) {
682 				flushq(q, FLUSHDATA);
683 			}
684 			/*
685 			 * here, if flush read queue, some key-up messages
686 			 * may be lost so that upper module or applications
687 			 * treat corresponding keys as being held down for
688 			 * ever.
689 			 */
690 			freemsg(mp);
691 			break;
692 
693 		case M_DATA:
694 			/*
695 			 * virtual keyboard doesn't support this interface.
696 			 * only when it is disabled, we pass the message
697 			 * down to lower queue.
698 			 */
699 			if ((conskbd.conskbd_bypassed) &&
700 			    (conskbd.conskbd_lqueue_nums > 0)) {
701 				if (putq(conskbd.conskbd_lqueue_list->
702 				    lqs_queue, mp) != 1)
703 					freemsg(mp);
704 			} else {
705 				freemsg(mp);
706 			}
707 			break;
708 
709 		default:
710 			/*
711 			 * Pass an error message up.
712 			 */
713 			mp->b_datap->db_type = M_ERROR;
714 			if (mp->b_cont) {
715 				freemsg(mp->b_cont);
716 				mp->b_cont = NULL;
717 			}
718 			mp->b_rptr = mp->b_datap->db_base;
719 			mp->b_wptr = mp->b_rptr + sizeof (char);
720 			*mp->b_rptr = EINVAL;
721 			qreply(q, mp);
722 		}
723 	}	/* end of while */
724 
725 }	/* conskbduwsrv() */
726 
727 static void
728 conskbdioctl(queue_t *q, mblk_t *mp)
729 {
730 	conskbd_lower_queue_t		*prev;
731 	conskbd_lower_queue_t		*lqs;
732 	struct	iocblk			*iocp;
733 	struct	linkblk			*linkp;
734 	int	index;
735 	int	error = 0;
736 
737 	iocp = (struct iocblk *)mp->b_rptr;
738 
739 	switch (iocp->ioc_cmd) {
740 
741 	case I_LINK:
742 	case I_PLINK:
743 		if (conskbd.conskbd_bypassed == B_TRUE) {
744 		/*
745 		 * A legacy keyboard can NOT be connected to conskbd together
746 		 * with other keyboards. So when a legacy keyboard is already
747 		 * linked under conkbd, we just reject all others.
748 		 */
749 			miocnak(q, mp, 0, EAGAIN);
750 			break;
751 		}
752 
753 		mutex_enter(&conskbd_lq_lock);
754 		conskbd_ioc_plink(q, mp);
755 		mutex_exit(&conskbd_lq_lock);
756 		break;
757 
758 	case I_UNLINK:
759 	case I_PUNLINK:
760 		mutex_enter(&conskbd_lq_lock);
761 		linkp = (struct linkblk *)mp->b_cont->b_rptr;
762 		prev = conskbd.conskbd_lqueue_list;
763 		for (lqs = prev; lqs; lqs = lqs->lqs_next) {
764 			if (lqs->lqs_queue == linkp->l_qbot) {
765 				if (prev == lqs)
766 					conskbd.conskbd_lqueue_list =
767 					    lqs->lqs_next;
768 				else
769 					prev->lqs_next = lqs->lqs_next;
770 
771 				lqs->lqs_queue->q_ptr =  NULL;
772 				conskbd.conskbd_lqueue_nums --;
773 				if (conskbd.conskbd_lqueue_nums == 0)
774 					conskbd.conskbd_layout = -1;
775 
776 				mutex_exit(&conskbd_lq_lock);
777 
778 				for (index = 0; index < KBTRANS_KEYNUMS_MAX;
779 				    index ++) {
780 					if (lqs->lqs_key_state[index] ==
781 					    KEY_PRESSED)
782 						kbtrans_streams_key(
783 						    conskbd.conskbd_kbtrans,
784 						    index,
785 						    KEY_RELEASED);
786 				}
787 
788 				kmem_free(lqs, sizeof (*lqs));
789 				miocack(q, mp, 0, 0);
790 				return;
791 			}
792 			prev = lqs;
793 		}
794 		mutex_exit(&conskbd_lq_lock);
795 		miocnak(q, mp, 0, EINVAL);
796 		break;
797 
798 	case KIOCSKABORTEN:
799 		/*
800 		 * Check if privileged
801 		 */
802 		if ((error = secpolicy_sys_config(iocp->ioc_cr, B_FALSE))) {
803 			miocnak(q, mp, 0, error);
804 			return;
805 		}
806 
807 		error = miocpullup(mp, sizeof (int));
808 		if (error != 0) {
809 			miocnak(q, mp, 0, error);
810 			return;
811 		}
812 
813 		abort_enable = *(int *)mp->b_cont->b_rptr;
814 		miocack(q, mp, 0, 0);
815 		break;
816 
817 	default:
818 		if (conskbd.conskbd_bypassed == B_TRUE) {
819 			conskbd_legacy_kbd_ioctl(q, mp);
820 		} else {
821 			conskbd_virtual_kbd_ioctl(q, mp);
822 		}
823 	}
824 
825 }	/* conskbdioctl() */
826 
827 
828 static void
829 conskbd_virtual_kbd_ioctl(queue_t *q, mblk_t *mp)
830 {
831 	struct iocblk		*iocp;
832 	mblk_t			*datap;
833 	int			cmd;
834 	int			error = 0;
835 
836 	iocp = (struct iocblk *)mp->b_rptr;
837 
838 	switch (iocp->ioc_cmd) {
839 	case KIOCLAYOUT:
840 		if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
841 			miocnak(q, mp, 0, ENOMEM);
842 			break;
843 		}
844 
845 		if (conskbd.conskbd_layout == -1)
846 			*(int *)datap->b_wptr = KBTRANS_USBKB_DEFAULT_LAYOUT;
847 		else
848 			*(int *)datap->b_wptr = conskbd.conskbd_layout;
849 
850 		datap->b_wptr += sizeof (int);
851 		if (mp->b_cont)
852 			freemsg(mp->b_cont);
853 		mp->b_cont = datap;
854 		miocack(q, mp, sizeof (int), 0);
855 		break;
856 
857 	case KIOCSLAYOUT:
858 		if (iocp->ioc_count != TRANSPARENT) {
859 			miocnak(q, mp, 0, EINVAL);
860 			break;
861 		}
862 		conskbd.conskbd_layout = *(intptr_t *)(mp->b_cont->b_rptr);
863 		miocack(q, mp, 0, 0);
864 		break;
865 
866 	case CONSOPENPOLLEDIO:
867 		error = miocpullup(mp, sizeof (struct cons_polledio *));
868 		if (error != 0) {
869 			miocnak(q, mp, 0, error);
870 			break;
871 		}
872 		if (conskbd.conskbd_lqueue_list == NULL) {
873 			miocnak(q, mp, 0, EINVAL);
874 			break;
875 		}
876 		conskbd_handle_downstream_msg(q, mp);
877 		break;
878 
879 	case CONSCLOSEPOLLEDIO:
880 		if (conskbd.conskbd_lqueue_list == NULL) {
881 			miocnak(q, mp, 0, EINVAL);
882 			break;
883 		}
884 		conskbd_handle_downstream_msg(q, mp);
885 		break;
886 
887 	case CONSSETABORTENABLE:
888 		/*
889 		 * To enable combined STOP-A(or F1-A) to trap into kmdb,
890 		 * the lower physical keyboard drivers are always told not
891 		 * to parse abort sequence(refer to consconfig_dacf module).
892 		 * Instead, lower drivers always send all keydown & keyup
893 		 * messages up to conskbd, so that when key STOP(or F1) is
894 		 * pressed on one keyboard and key A is pressed on another
895 		 * keyboard, the system could trap into kmdb.
896 		 *
897 		 * When we by kbtrans_streams_message() invoked kbtrans to
898 		 * handle ioctls in conskbduwsrv() routine, kbtrans module
899 		 * already handle the message though it returned to us a
900 		 * KBTRANS_MESSAGE_NOT_HANDLED. For virtual keyboard, no
901 		 * special initialization or un-initialization is needed.
902 		 * So we just return ACK to upper module.
903 		 */
904 		miocack(q, mp, 0, 0);
905 		break;
906 
907 	case KIOCCMD:
908 		if (conskbd.conskbd_lqueue_list == NULL ||
909 		    mp->b_cont == NULL) {
910 			miocnak(q, mp, 0, EINVAL);
911 			break;
912 		}
913 		cmd = *(int *)mp->b_cont->b_rptr;
914 		if (cmd == KBD_CMD_GETLAYOUT) {
915 			freemsg(mp->b_cont);
916 			datap = allocb(sizeof (int), BPRI_HI);
917 			if (datap == NULL) {
918 				miocnak(q, mp, 0, ENOMEM);
919 				return;
920 			}
921 			if (conskbd.conskbd_layout == -1)
922 				*(int *)datap->b_wptr =
923 				    KBTRANS_USBKB_DEFAULT_LAYOUT;
924 			else
925 				*(int *)datap->b_wptr = conskbd.conskbd_layout;
926 
927 			mp->b_cont = datap;
928 			miocack(q, mp, sizeof (int), 0);
929 			return;
930 		}
931 
932 		conskbd_handle_downstream_msg(q, mp);
933 		break;
934 
935 	default:
936 		miocnak(q, mp, 0, EINVAL);
937 		break;
938 	}
939 
940 }	/* conskbd_virtual_kbd_ioctl() */
941 
942 static void
943 conskbd_legacy_kbd_ioctl(queue_t *q, mblk_t *mp)
944 {
945 	conskbd_lower_queue_t	*lq;
946 	struct	iocblk		*iocp;
947 	int	error = 0;
948 
949 	iocp = (struct iocblk *)mp->b_rptr;
950 
951 	ASSERT(conskbd.conskbd_lqueue_nums == 1);
952 	switch (iocp->ioc_cmd) {
953 
954 	case KIOCGDIRECT: {
955 		mblk_t *datap;
956 
957 		if ((datap = allocb(sizeof (int), BPRI_MED)) == NULL) {
958 			miocnak(q, mp, 0, ENOMEM);
959 			break;
960 		}
961 
962 		*(int *)datap->b_wptr = conskbd.conskbd_directio;
963 		datap->b_wptr += sizeof (int);
964 		if (mp->b_cont != NULL) {
965 			freemsg(mp->b_cont);
966 			mp->b_cont = NULL;
967 		}
968 		mp->b_cont = datap;
969 		miocack(q, mp, sizeof (int), 0);
970 		break;
971 	}
972 
973 	case KIOCSDIRECT:
974 		error = miocpullup(mp, sizeof (int));
975 		if (error != 0) {
976 			miocnak(q, mp, 0, error);
977 			break;
978 		}
979 		conskbd.conskbd_directio = *(int *)mp->b_cont->b_rptr;
980 
981 		/*
982 		 * Pass this through, if there's something to pass
983 		 * it through to, so the system keyboard can reset
984 		 * itself.
985 		 */
986 		if (conskbd.conskbd_lqueue_nums > 0) {
987 			lq = conskbd.conskbd_lqueue_list;
988 			ASSERT(lq && lq->lqs_next == NULL);
989 			if (putq(lq->lqs_queue, mp) != 1) {
990 				miocnak(q, mp, 0, ENOMEM);
991 				return;
992 			}
993 			break;
994 		}
995 
996 		miocack(q, mp, 0, 0);
997 		break;
998 
999 	default:
1000 		/*
1001 		 * Pass this through, if there's something to pass it
1002 		 * through to; otherwise, reject it.
1003 		 */
1004 		if (conskbd.conskbd_lqueue_nums > 0) {
1005 			lq = conskbd.conskbd_lqueue_list;
1006 			ASSERT(lq && lq->lqs_next == NULL);
1007 			if (putq(lq->lqs_queue, mp) != 1) {
1008 				miocnak(q, mp, 0, ENOMEM);
1009 				return;
1010 			}
1011 			break;
1012 		}
1013 
1014 		/* nobody below us; reject it */
1015 		miocnak(q, mp, 0, EINVAL);
1016 		break;
1017 	}
1018 
1019 }	/* conskbd_legacy_kbd_ioctl() */
1020 
1021 
1022 /*
1023  * Service procedure for lower write queue.
1024  * Puts things on the queue below us, if it lets us.
1025  */
1026 static void
1027 conskbdlwserv(queue_t *q)
1028 {
1029 	register mblk_t *mp;
1030 
1031 	while (canput(q->q_next) && (mp = getq(q)) != NULL)
1032 		putnext(q, mp);
1033 
1034 }	/* conskbdlwserv() */
1035 
1036 /*
1037  * Put procedure for lower read queue.
1038  * Pass everything up to minor device 0 if "directio" set, otherwise to minor
1039  * device 1.
1040  */
1041 static void
1042 conskbdlrput(queue_t *q, mblk_t *mp)
1043 {
1044 	conskbd_lower_queue_t	*lqs;
1045 	struct iocblk 	*iocp;
1046 	Firm_event	*fe;
1047 
1048 	DPRINTF(PRINT_L1, PRINT_MASK_ALL, ("conskbdlrput\n"));
1049 
1050 	switch (mp->b_datap->db_type) {
1051 
1052 	case M_FLUSH:
1053 		if (*mp->b_rptr == FLUSHR) {
1054 			flushq(q, FLUSHDATA);	/* XXX doesn't flush M_DELAY */
1055 			*mp->b_rptr &= ~FLUSHR;	/* it has been flushed */
1056 		}
1057 		if (*mp->b_rptr == FLUSHW) {
1058 			flushq(WR(q), FLUSHDATA);
1059 			qreply(q, mp);	/* give the read queues a crack at it */
1060 		} else
1061 			freemsg(mp);
1062 		break;
1063 
1064 	case M_DATA:
1065 		if (conskbd.conskbd_bypassed == B_FALSE) {
1066 
1067 			fe = (Firm_event *)mp->b_rptr;
1068 
1069 			/*
1070 			 * This is a workaround.
1071 			 *
1072 			 * According to HID specification, there are the
1073 			 * following keycode mapping between PS2 and USB,
1074 			 *
1075 			 *	PS2 AT-101 keycode(29)  --->    USB(49)
1076 			 *	PS2 AT-102 keycode(42)  --->    USB(50)
1077 			 *
1078 			 * However, the two keys, AT-101(29) and AT-102(42),
1079 			 * have the same scancode,0x2B, in PS2 scancode SET1
1080 			 * which we are using. The Kb8042 driver always
1081 			 * recognizes the two keys as PS2(29) so that we could
1082 			 * not know which is being pressed or released when we
1083 			 * receive scancode 0x2B. Fortunately, the two keys can
1084 			 * not co-exist in a specific layout. In other words,
1085 			 * in the table of keycode-to-symbol mapping, either
1086 			 * entry 49 or 50 is a hole. So, if we're processing a
1087 			 * keycode 49, we look at the entry for 49.  If it's
1088 			 * HOLE, remap the key to 50; If we're processing a 50,
1089 			 * look at the entry for 50.  If it's HOLE, we remap
1090 			 * the key to 49.
1091 			 */
1092 			if (fe->id == 49 || fe->id == 50) {
1093 				if (conskbd_keyindex->k_normal[50] == HOLE)
1094 					fe->id = 49;
1095 				else
1096 					fe->id = 50;
1097 			}
1098 
1099 			/*
1100 			 * Remember key state of each key of lower physical
1101 			 * keyboard. When a keyboard is umplumbed from conskbd,
1102 			 * we will check all key states. By then,  we will fake
1103 			 * a KEY_RELEASED message for each key in KEY_PRESSED
1104 			 * state. Otherwise, upper module will treat these keys
1105 			 * as held-down for ever.
1106 			 */
1107 			iocp = (struct iocblk *)mp->b_rptr;
1108 			lqs = (conskbd_lower_queue_t *)q->q_ptr;
1109 			if (fe->value)
1110 				lqs->lqs_key_state[fe->id] = KEY_PRESSED;
1111 			else
1112 				lqs->lqs_key_state[fe->id] = KEY_RELEASED;
1113 
1114 			kbtrans_streams_key(conskbd.conskbd_kbtrans,
1115 			    fe->id, fe->value ? KEY_PRESSED : KEY_RELEASED);
1116 			freemsg(mp);
1117 		} else {
1118 			if (conskbd.conskbd_directio)
1119 				putnext(conskbd_regqueue, mp);
1120 			else if (conskbd_consqueue != NULL)
1121 				putnext(conskbd_consqueue, mp);
1122 			else
1123 				freemsg(mp);
1124 		}
1125 		conskbd_idle_stamp = gethrestime_sec();
1126 		break;
1127 
1128 	case M_IOCACK:
1129 	case M_IOCNAK:
1130 		iocp = (struct iocblk *)mp->b_rptr;
1131 		lqs = (conskbd_lower_queue_t *)q->q_ptr;
1132 
1133 		DPRINTF(PRINT_L1, PRINT_MASK_ALL, ("conskbdlrput: "
1134 		    "ACK/NAK - cmd 0x%x\n", iocp->ioc_cmd));
1135 
1136 		conskbd_lqs_ack_complete(lqs, mp);
1137 		break;
1138 
1139 	case M_ERROR:
1140 	case M_HANGUP:
1141 	default:
1142 		freemsg(mp);	/* anything useful here? */
1143 		break;
1144 	}
1145 
1146 }	/* conskbdlrput() */
1147 
1148 
1149 /* ARGSUSED */
1150 static int
1151 conskbd_kstat_update(kstat_t *ksp, int rw)
1152 {
1153 	if (rw == KSTAT_WRITE)
1154 		return (EACCES);
1155 
1156 	conskbd_kstat.idle_sec.value.l = gethrestime_sec() - conskbd_idle_stamp;
1157 
1158 	return (0);
1159 
1160 }	/* conskbd_kstat_update() */
1161 
1162 /*
1163  * STREAMS architecuture provides guarantee that the ID of each
1164  * message, iocblk.ioc_id, in a stream is unique. The following
1165  * routine performes the task: When receive request from upstream,
1166  * it saves the request in a global link list, clones the request,
1167  * and then sends a copy of the request to each of lower queues
1168  * which are plumbed into conskbd. And then, when receives responses
1169  * from lower queues in conskbdlrput() routine, we can know the
1170  * request matching received responses by searching the global linked
1171  * list to find the request which has the same message ID of the
1172  * response. Then, when all lower queues response this request, we
1173  * give a response to upstreams based the following policy:
1174  * If any one of lower queues acks our reuqest, then we return ack
1175  * to upstreams; only if all lower queues nak our request, we return
1176  * nak to upstreams. If all responses are nak, the error number of
1177  * the first response is sent to upstream.
1178  */
1179 static void
1180 conskbd_handle_downstream_msg(queue_t *q, mblk_t *mp)
1181 {
1182 	conskbd_pending_msg_t	*msg;
1183 	conskbd_lower_queue_t	*lqs;
1184 	struct iocblk	*iocp;
1185 	mblk_t		*clonemp;
1186 	int		retry;
1187 
1188 	if (conskbd.conskbd_lqueue_nums == 0) {
1189 		miocnak(q, mp, 0, EINVAL);
1190 		return;
1191 	}
1192 
1193 	msg = (conskbd_pending_msg_t *)
1194 	    kmem_zalloc(sizeof (conskbd_pending_msg_t), KM_SLEEP);
1195 	mutex_init(&msg->kpm_lock, NULL, MUTEX_DRIVER, NULL);
1196 	lqs = conskbd.conskbd_lqueue_list;
1197 	iocp = (struct iocblk *)mp->b_rptr;
1198 
1199 	ASSERT(iocp->ioc_cmd == CONSOPENPOLLEDIO ||
1200 	    iocp->ioc_cmd == CONSCLOSEPOLLEDIO ||
1201 	    iocp->ioc_cmd == KIOCCMD);
1202 
1203 	msg->kpm_upper_queue = q;
1204 	msg->kpm_req_msg = mp;
1205 	msg->kpm_req_id = iocp->ioc_id;
1206 	msg->kpm_req_cmd = iocp->ioc_cmd;
1207 	msg->kpm_req_nums = conskbd.conskbd_lqueue_nums;
1208 	conskbd_mux_enqueue_msg(msg);
1209 
1210 	for (retry = 0, lqs = conskbd.conskbd_lqueue_list; lqs; ) {
1211 
1212 		/*
1213 		 * if a lower physical keyboard is not in polled I/O
1214 		 * mode, we couldn't send CONSCLOSEPOLLEDIO to it,
1215 		 * otherwise, system will panic.
1216 		 */
1217 		if (iocp->ioc_cmd == CONSCLOSEPOLLEDIO &&
1218 		    lqs->lqs_polledio == NULL) {
1219 			lqs = lqs->lqs_next;
1220 			msg->kpm_req_nums --;
1221 			retry = 0;
1222 			continue;
1223 		}
1224 
1225 		clonemp = copymsg(mp);
1226 		if (clonemp != NULL) {
1227 			if (putq(lqs->lqs_queue, clonemp) == 1) {
1228 				lqs = lqs->lqs_next;
1229 				retry = 0;
1230 				continue;
1231 			}
1232 
1233 			/*
1234 			 * failed to invoke putq(), retry.
1235 			 */
1236 			freemsg(clonemp);
1237 		}
1238 
1239 		/*
1240 		 * During testing it was observed that occasionally
1241 		 * copymsg() would fail during boot. The reason for
1242 		 * these failures is unknown. Since we really want
1243 		 * to successfully plumb up all the attached keyboards
1244 		 * during boot we do a best effort here by retrying
1245 		 * the copymsg() call in the hopes that it will
1246 		 * succeeded upon subsequent invocations.
1247 		 *
1248 		 * If all the calls to copymsg() fails, it will cause
1249 		 * the corresponding keyboard to be unavailable, or
1250 		 * or behave weirdly,
1251 		 *
1252 		 * 1) for CONSOPENPOLLEDIO
1253 		 *	if copymsg()fails, the corresponding keyboard
1254 		 *	is not available in polled I/O mode once
1255 		 *	entering kmdb;
1256 		 * 2) for CONSCLOSEPOLLEDIO
1257 		 *	if copymsg() fails, the corresponding keyboard
1258 		 *	is not available in normal mode once returning
1259 		 *	from kmdb;
1260 		 * 3) for KIOCCMD
1261 		 * 	3.1) for KBD_CMD_NOBELL
1262 		 * 		there's no beep in USB and PS2 keyboard,
1263 		 * 		this ioctl actually disables the beep on
1264 		 * 		system mainboard. Note that all the cloned
1265 		 * 		messages sent down to lower queues do the
1266 		 * 		same job for system mainboard. Therefore,
1267 		 * 		even if we fail to send this ioctl to most
1268 		 * 		of lower queues, the beep still would be
1269 		 * 		disabled. So, no trouble exists here.
1270 		 *	3.2) for others
1271 		 *		nothing;
1272 		 *
1273 		 * However, all cases could be resume next time when the
1274 		 * same request comes again.
1275 		 */
1276 		if (retry ++ >= 5) {
1277 			dev_t	devt;
1278 			char	path[MAXPATHLEN + 1];
1279 
1280 			devt = lqs->lqs_queue->q_stream->sd_vnode->v_rdev;
1281 			switch (iocp->ioc_cmd) {
1282 			case CONSOPENPOLLEDIO:
1283 				if (ddi_dev_pathname(devt, S_IFCHR,
1284 				    path) == DDI_SUCCESS)
1285 					cmn_err(CE_WARN, "conskbd: "
1286 					    "keyboard is not available"
1287 					    " for system debugging: %s",
1288 					    path);
1289 				break;
1290 
1291 			case CONSCLOSEPOLLEDIO:
1292 				if (ddi_dev_pathname(devt, S_IFCHR,
1293 				    path) == DDI_SUCCESS)
1294 					cmn_err(CE_WARN, "conskbd: "
1295 					    "keyboard is not available:"
1296 					    " %s", path);
1297 				break;
1298 
1299 			default:
1300 				break;
1301 			}
1302 			msg->kpm_req_nums --;
1303 			lqs = lqs->lqs_next;
1304 			retry = 0;
1305 		}
1306 	}
1307 
1308 	if (msg->kpm_req_nums == 0) {
1309 		conskbd_mux_dequeue_msg(msg);
1310 		kmem_free(msg, sizeof (*msg));
1311 		miocnak(q, mp, 0, ENOMEM);
1312 	}
1313 
1314 }	/* conskbd_handle_downstream_msg() */
1315 
1316 
1317 static void
1318 conskbd_ioc_plink(queue_t *q, mblk_t *mp)
1319 {
1320 	mblk_t		*req;
1321 	queue_t		*lowque;
1322 	struct iocblk		*iocp;
1323 	struct linkblk		*linkp;
1324 	conskbd_lower_queue_t	*lqs;
1325 
1326 	ASSERT(mutex_owned(&conskbd_lq_lock));
1327 
1328 	lqs = kmem_zalloc(sizeof (*lqs), KM_SLEEP);
1329 	ASSERT(lqs->lqs_state == LQS_UNINITIALIZED);
1330 
1331 	iocp = (struct iocblk *)mp->b_rptr;
1332 	linkp = (struct linkblk *)mp->b_cont->b_rptr;
1333 	lowque = linkp->l_qbot;
1334 
1335 	lowque->q_ptr = (void *)lqs;
1336 	OTHERQ(lowque)->q_ptr = (void *)lqs;
1337 
1338 	lqs->lqs_queue = lowque;
1339 	lqs->lqs_pending_plink = mp;
1340 	lqs->lqs_pending_queue = q;
1341 
1342 	req = mkiocb(CONSSETKBDTYPE);
1343 	if (req == NULL) {
1344 		miocnak(q, mp, 0, ENOMEM);
1345 		lowque->q_ptr = NULL;
1346 		kmem_free(lqs, sizeof (*lqs));
1347 		return;
1348 	}
1349 
1350 	req->b_cont = allocb(sizeof (int), BPRI_MED);
1351 	if (req->b_cont == NULL) {
1352 		freemsg(req);
1353 		miocnak(q, mp, 0, ENOMEM);
1354 		lowque->q_ptr = NULL;
1355 		kmem_free(lqs, sizeof (*lqs));
1356 		return;
1357 	}
1358 
1359 	iocp->ioc_count = 0;
1360 	iocp->ioc_rval = 0;
1361 
1362 	*(int *)req->b_cont->b_wptr = KB_USB;
1363 	req->b_cont->b_wptr += sizeof (int);
1364 
1365 	lqs->lqs_state = LQS_KIOCTYPE_ACK_PENDING;
1366 
1367 	if (putq(lowque, req) != 1) {
1368 		freemsg(req);
1369 		miocnak(lqs->lqs_pending_queue,
1370 		    lqs->lqs_pending_plink, 0, ENOMEM);
1371 		lowque->q_ptr = NULL;
1372 		kmem_free(lqs, sizeof (*lqs));
1373 	}
1374 
1375 }	/* conskbd_ioc_plink() */
1376 
1377 
1378 /*
1379  * Every physical keyboard has a corresponding STREAMS queue. We call this
1380  * queue lower queue. Every lower queue has a state, refer to conskbd.h file
1381  * about "enum conskbd_lqs_state".
1382  * The following routine is used to handle response messages from lower queue.
1383  * When receiving ack/nak message from lower queue(s), the routine determines
1384  * the passage for it according to the current state of this lower queue.
1385  */
1386 static void
1387 conskbd_lqs_ack_complete(conskbd_lower_queue_t *lqs, mblk_t *mp)
1388 {
1389 	switch (lqs->lqs_state) {
1390 
1391 	/* S6: working in virtual keyboard mode, multi-keyboards are usable */
1392 	case LQS_INITIALIZED:
1393 		conskbd_mux_upstream_msg(lqs, mp);
1394 		break;
1395 
1396 	/* S5: working in legacy mode, only one keyboard is usable */
1397 	case LQS_INITIALIZED_LEGACY:
1398 		conskbd_legacy_upstream_msg(lqs, mp);
1399 		break;
1400 
1401 	/* S4: wait lower queue to acknowledge KIOCSLED  message */
1402 	case LQS_KIOCSLED_ACK_PENDING:
1403 		conskbd_kiocsled_complete(lqs, mp);
1404 		break;
1405 
1406 	/* S3: wait lower queue to acknowledge KIOCLAYOUT  message */
1407 	case LQS_KIOCLAYOUT_ACK_PENDING:
1408 		conskbd_kioclayout_complete(lqs, mp);
1409 		break;
1410 
1411 	/* S2: wait lower queue to acknowledge KIOCTRANS  message */
1412 	case LQS_KIOCTRANS_ACK_PENDING:
1413 		conskbd_kioctrans_complete(lqs, mp);
1414 		break;
1415 
1416 	/* S1: wait lower queue to acknowledge KIOCTYPE  message */
1417 	case LQS_KIOCTYPE_ACK_PENDING:
1418 		conskbd_kioctype_complete(lqs, mp);
1419 		break;
1420 
1421 	/* if reaching here, there must be a error */
1422 	default:
1423 		freemsg(mp);
1424 		cmn_err(CE_WARN, "conskbd: lqs_ack_complete() state error");
1425 		break;
1426 	}
1427 
1428 }	/* conskbd_lqs_ack_complete() */
1429 
1430 
1431 static void
1432 conskbd_kioctype_complete(conskbd_lower_queue_t *lqs, mblk_t *mp)
1433 {
1434 	struct iocblk	*iocp;
1435 	mblk_t		*msg;
1436 	mblk_t		*req;
1437 	queue_t		*lowerque;
1438 
1439 	ASSERT(lqs->lqs_pending_plink);
1440 	ASSERT(lqs->lqs_state == LQS_KIOCTYPE_ACK_PENDING);
1441 
1442 	lowerque = lqs->lqs_queue;
1443 
1444 	switch (mp->b_datap->db_type) {
1445 	case M_IOCACK:
1446 		req = mkiocb(KIOCTRANS);
1447 		if (req == NULL) {
1448 			miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1449 			    0, ENOMEM);
1450 			lowerque->q_ptr = NULL;
1451 			kmem_free(lqs, sizeof (*lqs));
1452 			freemsg(mp);
1453 			return;
1454 		}
1455 
1456 		req->b_cont = allocb(sizeof (int), BPRI_MED);
1457 		if (req->b_cont == NULL) {
1458 			miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1459 			    0, ENOMEM);
1460 			lowerque->q_ptr = NULL;
1461 			kmem_free(lqs, sizeof (*lqs));
1462 			freemsg(req);
1463 			freemsg(mp);
1464 			return;
1465 		}
1466 
1467 		/* Set the translate mode to TR_UNTRANS_EVENT */
1468 		*(int *)req->b_cont->b_wptr = TR_UNTRANS_EVENT;
1469 		req->b_cont->b_wptr += sizeof (int);
1470 
1471 		/* Ready to handle the response to KIOCTRANS */
1472 		lqs->lqs_state = LQS_KIOCTRANS_ACK_PENDING;
1473 
1474 		if (putq(lowerque, req) != 1) {
1475 			freemsg(req);
1476 			miocnak(lqs->lqs_pending_queue,
1477 			    lqs->lqs_pending_plink, 0, ENOMEM);
1478 			lowerque->q_ptr = NULL;
1479 			kmem_free(lqs, sizeof (*lqs));
1480 		}
1481 		break;
1482 
1483 	case M_IOCNAK:
1484 		/*
1485 		 * The lower keyboard driver can't mimic USB keyboard,
1486 		 * that's say, the physical keyboard is an old one, such
1487 		 * as TYPE 3/4/5 one. In this case, the virtual keyboard
1488 		 * is disabled, and the data from lower keyboard driver
1489 		 * will bypass the conskbd module.
1490 		 */
1491 
1492 		/*
1493 		 * if there is any other keyborad already linked under the
1494 		 * conskbd, we reject the current one.
1495 		 */
1496 		if (conskbd.conskbd_lqueue_nums > 0) {
1497 			iocp = (struct iocblk *)mp->b_rptr;
1498 			miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1499 			    0, iocp->ioc_error);
1500 			lowerque->q_ptr = NULL;
1501 			kmem_free(lqs, sizeof (*lqs));
1502 			break;
1503 		}
1504 
1505 		/*
1506 		 * Bypass the virutal keyboard for old hardware
1507 		 */
1508 		conskbd.conskbd_bypassed = B_TRUE;
1509 
1510 		msg = lqs->lqs_pending_plink;
1511 		msg->b_datap->db_type = M_IOCACK;
1512 		iocp = (struct iocblk *)msg->b_rptr;
1513 		iocp->ioc_error = 0;
1514 
1515 		/*
1516 		 * link this keyboard under conskbd
1517 		 */
1518 		mutex_enter(&conskbd_lq_lock);
1519 		lqs->lqs_next = conskbd.conskbd_lqueue_list;
1520 		conskbd.conskbd_lqueue_list = lqs;
1521 		conskbd.conskbd_lqueue_nums++;
1522 		mutex_exit(&conskbd_lq_lock);
1523 
1524 		lqs->lqs_state = LQS_INITIALIZED_LEGACY;
1525 
1526 		qreply(lqs->lqs_pending_queue, lqs->lqs_pending_plink);
1527 		break;
1528 	}
1529 
1530 	freemsg(mp);
1531 
1532 }	/* conskbd_kioctype_complete() */
1533 
1534 static void
1535 conskbd_kioctrans_complete(conskbd_lower_queue_t *lqs, mblk_t *mp)
1536 {
1537 	struct iocblk 	*iocp;
1538 	mblk_t		*req;
1539 	queue_t		*lowerque;
1540 
1541 	ASSERT(lqs->lqs_pending_plink != NULL);
1542 	ASSERT(lqs->lqs_state == LQS_KIOCTRANS_ACK_PENDING);
1543 
1544 	lowerque = lqs->lqs_queue;
1545 
1546 	switch (mp->b_datap->db_type) {
1547 	case M_IOCACK:
1548 		req = mkiocb(KIOCLAYOUT);
1549 		if (req == NULL) {
1550 			miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1551 			    0, ENOMEM);
1552 			lowerque->q_ptr = NULL;
1553 			kmem_free(lqs, sizeof (*lqs));
1554 			freemsg(mp);
1555 			return;
1556 		}
1557 
1558 		req->b_cont = allocb(sizeof (int), BPRI_MED);
1559 		if (req->b_cont == NULL) {
1560 			miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1561 			    0, ENOMEM);
1562 			kmem_free(lqs, sizeof (*lqs));
1563 			freemsg(req);
1564 			freemsg(mp);
1565 			return;
1566 		}
1567 
1568 		/* waiting for response to KIOCLAYOUT */
1569 		lqs->lqs_state = LQS_KIOCLAYOUT_ACK_PENDING;
1570 		if (putq(lqs->lqs_queue, req) != 1) {
1571 			freemsg(req);
1572 			miocnak(lqs->lqs_pending_queue,
1573 			    lqs->lqs_pending_plink, 0, ENOMEM);
1574 			lowerque->q_ptr = NULL;
1575 			kmem_free(lqs, sizeof (*lqs));
1576 		}
1577 		break;
1578 
1579 	case M_IOCNAK:
1580 		iocp = (struct iocblk *)mp->b_rptr;
1581 		miocnak(lqs->lqs_pending_queue, lqs->lqs_pending_plink,
1582 		    0, iocp->ioc_error);
1583 		lowerque->q_ptr = NULL;
1584 		kmem_free(lqs, sizeof (*lqs));
1585 		break;
1586 	}
1587 
1588 	freemsg(mp);
1589 
1590 }	/* conskbd_kioctrans_complete() */
1591 
1592 static void
1593 conskbd_kioclayout_complete(conskbd_lower_queue_t *lqs, mblk_t *mp)
1594 {
1595 	mblk_t		*req;
1596 	int		layout;
1597 	boolean_t	fail;
1598 
1599 	ASSERT(lqs->lqs_pending_plink != NULL);
1600 	ASSERT(lqs->lqs_state == LQS_KIOCLAYOUT_ACK_PENDING);
1601 
1602 	switch (mp->b_datap->db_type) {
1603 	case M_IOCACK:
1604 		if (miocpullup(mp, sizeof (int)) == 0) {
1605 			layout = *(int *)mp->b_cont->b_rptr;
1606 			/*
1607 			 * We just accept the layout of the first keyboard
1608 			 * requesting to be linked under conskbd. If current
1609 			 * keyboard is the first one, and if we get right
1610 			 * layout from it, we set conskbd's layout
1611 			 */
1612 			if (layout != -1 && conskbd.conskbd_layout == -1)
1613 				conskbd.conskbd_layout = layout;
1614 		}
1615 		break;
1616 
1617 
1618 	/* if fail, leave conskbd's layout as it is */
1619 	case M_IOCNAK:
1620 		break;
1621 	}
1622 
1623 	freemsg(mp);
1624 
1625 	fail = B_TRUE;
1626 	req = mkiocb(KIOCSLED);
1627 	if (req) {
1628 		req->b_cont = allocb(sizeof (uchar_t), BPRI_MED);
1629 		if (req->b_cont) {
1630 			*(uchar_t *)req->b_cont->b_wptr =
1631 			    conskbd.conskbd_led_state;
1632 			req->b_cont->b_wptr += sizeof (uchar_t);
1633 
1634 			/* waiting for response to KIOCSLED */
1635 			lqs->lqs_state = LQS_KIOCSLED_ACK_PENDING;
1636 			if (putq(lqs->lqs_queue, req) == 1) {
1637 				fail = B_FALSE;
1638 			} else {
1639 				freemsg(req);
1640 			}
1641 
1642 		} else {
1643 			freemsg(req);
1644 		}
1645 	}
1646 
1647 	if (fail) {
1648 		/*
1649 		 * If fail to allocate KIOCSLED message or put the message
1650 		 * into lower queue, we immediately link current keyboard
1651 		 * under conskbd. Thus, even if fails to set LED, this
1652 		 * keyboard could be available.
1653 		 */
1654 		conskbd_link_lower_queue(lqs);
1655 	}
1656 
1657 }	/* conskbd_kioclayout_complete() */
1658 
1659 
1660 static void
1661 conskbd_kiocsled_complete(conskbd_lower_queue_t *lqs, mblk_t *mp)
1662 {
1663 	ASSERT(lqs->lqs_pending_plink != NULL);
1664 	ASSERT(lqs->lqs_state == LQS_KIOCSLED_ACK_PENDING);
1665 
1666 	/*
1667 	 * Basically, failure of setting LED is not a fatal error,
1668 	 * so we will plumb the lower queue into conskbd whether
1669 	 * setting LED succeeds or fails.
1670 	 */
1671 	freemsg(mp);
1672 	conskbd_link_lower_queue(lqs);
1673 
1674 }	/* conskbd_kiocsled_complete() */
1675 
1676 
1677 static void
1678 conskbd_mux_upstream_msg(conskbd_lower_queue_t *lqs, mblk_t *mp)
1679 {
1680 	conskbd_pending_msg_t	*msg;
1681 	struct iocblk		*iocp;
1682 	int			error;
1683 	dev_t			devt;
1684 	char			path[MAXPATHLEN + 1];
1685 
1686 	ASSERT(lqs->lqs_state == LQS_INITIALIZED);
1687 	msg = conskbd_mux_find_msg(mp);
1688 
1689 	if (!msg) {
1690 		/*
1691 		 * Here, we just discard the responses to KIOCSLED request.
1692 		 * Please refer to conskbd_streams_setled().
1693 		 */
1694 		ASSERT(((struct iocblk *)mp->b_rptr)->ioc_cmd == KIOCSLED);
1695 		freemsg(mp);
1696 		return;
1697 	}
1698 
1699 	/*
1700 	 * We use the b_next field of mblk_t structure to link all
1701 	 * response coming from lower queues into a linkage list,
1702 	 * and make use of the b_prev field to save a pointer to
1703 	 * the lower queue from which the current response message
1704 	 * comes.
1705 	 */
1706 	ASSERT(mp->b_next == NULL && mp->b_prev == NULL);
1707 	mutex_enter(&msg->kpm_lock);
1708 	mp->b_next = msg->kpm_resp_list;
1709 	mp->b_prev = (mblk_t *)lqs;
1710 	msg->kpm_resp_list = mp;
1711 	msg->kpm_resp_nums ++;
1712 	mutex_exit(&msg->kpm_lock);
1713 
1714 	if (msg->kpm_resp_nums < msg->kpm_req_nums)
1715 		return;
1716 
1717 	ASSERT(msg->kpm_resp_nums == msg->kpm_req_nums);
1718 	ASSERT(mp == msg->kpm_resp_list);
1719 
1720 	conskbd_mux_dequeue_msg(msg);
1721 
1722 
1723 	/*
1724 	 * Here, we have the policy that, if any one lower queue ACK
1725 	 * our reuqest, then we return ACK to upstreams; only if all
1726 	 * lower queues NAK our request, we return NAK to upstreams.
1727 	 * if all responses are nak, the errno of the  first response
1728 	 * is sent to upstreams
1729 	 */
1730 	ASSERT(mp->b_rptr);
1731 	error = ((struct iocblk *)mp->b_rptr)->ioc_error;
1732 
1733 	switch (msg->kpm_req_cmd) {
1734 	case CONSOPENPOLLEDIO:
1735 		/*
1736 		 * Here, we can safely ignore the NAK message. If any one lower
1737 		 * queue returns NAK, the pointer to the corresponding polledio
1738 		 * structure will remain null, that's say lqs->lqs_polledio =
1739 		 * null. When we need to invoke polled I/O interface, we will
1740 		 * check if the pointer is null.
1741 		 */
1742 		for (mp = msg->kpm_resp_list; mp; ) {
1743 			cons_polledio_t		*polledio;
1744 
1745 			msg->kpm_resp_list = mp->b_next;
1746 			lqs = (conskbd_lower_queue_t *)mp->b_prev;
1747 			devt = lqs->lqs_queue->q_stream->sd_vnode->v_rdev;
1748 			if (mp->b_datap->db_type == M_IOCACK) {
1749 				polledio = *(struct cons_polledio **)
1750 				    mp->b_cont->b_rptr;
1751 				if (polledio->cons_polledio_version ==
1752 				    CONSPOLLEDIO_V1) {
1753 					lqs->lqs_polledio = polledio;
1754 					error = 0;
1755 				} else {
1756 					/*
1757 					 * USB and PS2 keyboard drivers should
1758 					 * use the same cons_polledio structure
1759 					 * as conskbd.
1760 					 */
1761 					if (ddi_dev_pathname(devt, S_IFCHR,
1762 					    path) == DDI_SUCCESS) {
1763 						cmn_err(CE_WARN, "keyboard "
1764 						    "driver does not support "
1765 						    "system debugging: %s",
1766 						    path);
1767 					}
1768 					error = EINVAL;
1769 				}
1770 			} else {
1771 				if (ddi_dev_pathname(devt, S_IFCHR, path) ==
1772 				    DDI_SUCCESS) {
1773 					cmn_err(CE_WARN, "conskbd: keyboard is"
1774 					    " not available for system"
1775 					    " debugging:  %s", path);
1776 				}
1777 			}
1778 			mp->b_next = NULL;
1779 			mp->b_prev = NULL;
1780 			freemsg(mp);
1781 			mp = msg->kpm_resp_list;
1782 		}
1783 
1784 		mp = msg->kpm_req_msg;
1785 		if (error == 0) {
1786 			*(struct cons_polledio **)mp->b_cont->b_rptr =
1787 			    &conskbd.conskbd_polledio;
1788 		}
1789 		break;
1790 
1791 	case CONSCLOSEPOLLEDIO:
1792 		for (mp = msg->kpm_resp_list; mp; ) {
1793 			msg->kpm_resp_list = mp->b_next;
1794 			lqs = (conskbd_lower_queue_t *)mp->b_prev;
1795 			if (mp->b_datap->db_type == M_IOCACK) {
1796 				lqs->lqs_polledio = NULL;
1797 				error = 0;
1798 			} else {
1799 				devt =
1800 				    lqs->lqs_queue->q_stream->sd_vnode->v_rdev;
1801 
1802 				if (ddi_dev_pathname(devt, S_IFCHR, path) ==
1803 				    DDI_SUCCESS) {
1804 					cmn_err(CE_WARN, "conskbd: keyboard is"
1805 					    " not available: %s", path);
1806 				}
1807 			}
1808 
1809 			mp->b_next = NULL;
1810 			mp->b_prev = NULL;
1811 			freemsg(mp);
1812 			mp = msg->kpm_resp_list;
1813 		}
1814 		break;
1815 
1816 	case KIOCCMD:
1817 		for (mp = msg->kpm_resp_list; mp; ) {
1818 			msg->kpm_resp_list = mp->b_next;
1819 
1820 			if (mp->b_datap->db_type == M_IOCACK)
1821 				error = 0;
1822 			mp->b_next = NULL;
1823 			mp->b_prev = NULL;
1824 			freemsg(mp);
1825 			mp = msg->kpm_resp_list;
1826 		}
1827 		break;
1828 
1829 	default:  /* it is impossible to reach here */
1830 		cmn_err(CE_WARN, "conskbd: unexpected ioctl reply");
1831 	}
1832 
1833 	mp = msg->kpm_req_msg;
1834 	if (error == 0) {
1835 		mp->b_datap->db_type = M_IOCACK;
1836 	} else {
1837 		mp->b_datap->db_type = M_IOCNAK;
1838 	}
1839 	iocp = (struct iocblk *)mp->b_rptr;
1840 	iocp->ioc_error = error;
1841 	qreply(msg->kpm_upper_queue, mp);
1842 	mutex_destroy(&msg->kpm_lock);
1843 	kmem_free(msg, sizeof (*msg));
1844 
1845 }	/* conskbd_mux_upstream_msg() */
1846 
1847 
1848 static void
1849 conskbd_link_lower_queue(conskbd_lower_queue_t *lqs)
1850 {
1851 	struct iocblk 	*iocp;
1852 	mblk_t		*msg;
1853 	int		index;
1854 
1855 	ASSERT(lqs->lqs_pending_plink != NULL);
1856 
1857 	msg = lqs->lqs_pending_plink;
1858 	msg->b_datap->db_type = M_IOCACK;
1859 	iocp = (struct iocblk *)msg->b_rptr;
1860 	iocp->ioc_error = 0;
1861 
1862 	/*
1863 	 * Now, link the lower queue under conskbd
1864 	 */
1865 	mutex_enter(&conskbd_lq_lock);
1866 	conskbd.conskbd_lqueue_nums++;
1867 	lqs->lqs_next = conskbd.conskbd_lqueue_list;
1868 	conskbd.conskbd_lqueue_list = lqs;
1869 	for (index = 0; index < KBTRANS_KEYNUMS_MAX; index ++) {
1870 		lqs->lqs_key_state[index] = KEY_RELEASED;
1871 	}
1872 	lqs->lqs_state = LQS_INITIALIZED;
1873 	mutex_exit(&conskbd_lq_lock);
1874 	qreply(lqs->lqs_pending_queue, lqs->lqs_pending_plink);
1875 
1876 }	/* conskbd_kiocsled_complete() */
1877 
1878 
1879 
1880 /*ARGSUSED*/
1881 static void
1882 conskbd_legacy_upstream_msg(conskbd_lower_queue_t *lqs, mblk_t *mp)
1883 {
1884 	struct iocblk	*iocp;
1885 
1886 	ASSERT(lqs && lqs->lqs_state == LQS_INITIALIZED_LEGACY);
1887 
1888 	/*
1889 	 * We assume that all of the ioctls are headed to the
1890 	 * conskbd_regqueue if it is open.  We are intercepting a few ioctls
1891 	 * that we know belong to conskbd_consqueue, and sending them there.
1892 	 * Any other, new ioctls that have to be routed to conskbd_consqueue
1893 	 * should be added to this list.
1894 	 */
1895 	iocp = (struct iocblk *)mp->b_rptr;
1896 
1897 	if ((iocp->ioc_cmd == CONSOPENPOLLEDIO) ||
1898 			(iocp->ioc_cmd == CONSCLOSEPOLLEDIO)) {
1899 
1900 		DPRINTF(PRINT_L1, PRINT_MASK_ALL,
1901 			("conskbd_legacy_upstream_msg: "
1902 			"CONSOPEN/CLOSEPOLLEDIO ACK/NAK\n"));
1903 		putnext(conskbd_consqueue, mp);
1904 
1905 	} else if (conskbd_regqueue != NULL) {
1906 		DPRINTF(PRINT_L1, PRINT_MASK_ALL,
1907 		    ("conskbd_legacy_upstream_msg: conskbd_regqueue != NULL"));
1908 
1909 		putnext(conskbd_regqueue, mp);
1910 
1911 	} else if (conskbd_consqueue != NULL) {
1912 		DPRINTF(PRINT_L1, PRINT_MASK_ALL,
1913 		    ("conskbd_legacy_upstream_msg: conskbd_consqueue != NULL"));
1914 		putnext(conskbd_consqueue, mp);
1915 	} else {
1916 		/* if reached here, it must be a error */
1917 		cmn_err(CE_WARN,
1918 		    "kb:  no destination for IOCACK/IOCNAK!");
1919 		freemsg(mp);
1920 	}
1921 
1922 }	/* conskbd_legacy_upstream_msg() */
1923 
1924 /*
1925  * This routine is a callback routine for kbtrans module to set LED.
1926  * Kbtrans will invoke it in two cases:
1927  *
1928  * 1) application initiated request
1929  * 	A KIOCSLED ioctl is sent by an application. The ioctl will be
1930  * 	be prcoessed by queue service procedure conskbduwsrv(), which
1931  * 	in turn calls kbtrans to process the ioctl. Then kbtrans invokes
1932  * 	conskbd_streams_setled() to set LED, after that,  kbtrans will
1933  * 	return an ACK message to upper module.
1934  *
1935  * 2) Kbtrans initiated the request
1936  *	When conskbd works in TR_ASCII translation mode, if anyone of
1937  *	CapsLock, NumberLock and Compose keys is pressed, kbtrans need
1938  *	to set LED. In this case, there is no ioctl from upper module.
1939  *	There is no requirement to send response to somebody.
1940  *
1941  * In first case, kbtrans will send response to upper module; and in the
1942  * second, we don't need to send response. So conskbd_streams_setled()
1943  * has no return value.
1944  */
1945 static void
1946 conskbd_streams_setled(struct kbtrans_hardware *hw, int led_state)
1947 {
1948 	conskbd_state_t  *conskbdp = (conskbd_state_t *)hw;
1949 	conskbd_lower_queue_t *lqs;
1950 	mblk_t		*req;
1951 
1952 	ASSERT(&conskbd == conskbdp);
1953 
1954 	if (led_state == -1)
1955 		return;
1956 
1957 	conskbdp->conskbd_led_state = led_state;
1958 
1959 	/*
1960 	 * Basically, failing to set LED is not a fatal error, we just skip
1961 	 * it if this happens.
1962 	 */
1963 	for (lqs = conskbdp->conskbd_lqueue_list; lqs; lqs = lqs->lqs_next) {
1964 		req = mkiocb(KIOCSLED);
1965 
1966 		if (!req) {
1967 			continue;
1968 		}
1969 
1970 		req->b_cont = allocb(sizeof (uchar_t), BPRI_MED);
1971 		if (!req->b_cont) {
1972 			freemsg(req);
1973 			continue;
1974 		}
1975 		*(uchar_t *)req->b_cont->b_wptr = led_state;
1976 		req->b_cont->b_wptr += sizeof (uchar_t);
1977 		if (putq(lqs->lqs_queue, req) != 1)
1978 			freemsg(req);
1979 	}
1980 
1981 }	/* conskbd_streams_setled() */
1982 
1983 static void
1984 conskbd_polledio_setled(struct kbtrans_hardware *hw, int led_state)
1985 {
1986 	conskbd_state_t  *conskbdp = (conskbd_state_t *)hw;
1987 	struct cons_polledio		*cb;
1988 	conskbd_lower_queue_t	*lqs;
1989 
1990 	for (lqs = conskbdp->conskbd_lqueue_list; lqs; lqs = lqs->lqs_next) {
1991 		cb = lqs->lqs_polledio;
1992 		if ((cb != NULL) && (cb->cons_polledio_setled != NULL)) {
1993 			cb->cons_polledio_setled(cb->cons_polledio_argument,
1994 			    led_state);
1995 		}
1996 	}
1997 
1998 }	/* conskbd_polledio_setled() */
1999 
2000 static boolean_t
2001 conskbd_polled_keycheck(struct kbtrans_hardware *hw,
2002 		kbtrans_key_t *keycode, enum keystate *state)
2003 {
2004 	conskbd_state_t  *conskbdp = (conskbd_state_t *)hw;
2005 	struct cons_polledio 		*cb;
2006 	conskbd_lower_queue_t	*lqs;
2007 	boolean_t	ret = B_FALSE;
2008 
2009 	for (ret = B_FALSE, lqs = conskbdp->conskbd_lqueue_list; lqs != NULL;
2010 	    lqs = lqs->lqs_next) {
2011 		cb = lqs->lqs_polledio;
2012 		if ((cb != NULL) &&
2013 		    (cb->cons_polledio_keycheck != NULL)) {
2014 			ret = cb->cons_polledio_keycheck(
2015 			    cb->cons_polledio_argument, keycode, state);
2016 		}
2017 
2018 		/* Get a char from lower queue(hardware) ? */
2019 		if (ret == B_TRUE) {
2020 			break;
2021 		}
2022 	}
2023 
2024 	return (ret);
2025 
2026 }	/* conskbd_polled_keycheck() */
2027 
2028 static boolean_t
2029 conskbd_override_kbtrans(queue_t *q, mblk_t *mp)
2030 {
2031 	struct iocblk		*iocp;
2032 	int		directio;
2033 	int		error;
2034 
2035 	if (mp->b_datap->db_type != M_IOCTL)
2036 		return (B_FALSE);
2037 
2038 	iocp = (struct iocblk *)mp->b_rptr;
2039 
2040 	switch (iocp->ioc_cmd) {
2041 	case KIOCGDIRECT: {
2042 		/*
2043 		 * Don't let the kbtrans-based code see this; it will
2044 		 * respond incorrectly.
2045 		 */
2046 		register mblk_t *datap;
2047 
2048 		if ((datap = allocb((int)sizeof (int), BPRI_MED)) == NULL) {
2049 			miocnak(q, mp, 0, ENOMEM);
2050 			return (B_TRUE);
2051 		}
2052 
2053 		*(int *)datap->b_wptr = conskbd.conskbd_directio;
2054 		datap->b_wptr += sizeof (int);
2055 		if (mp->b_cont) {
2056 			freemsg(mp->b_cont);
2057 			mp->b_cont = NULL;
2058 		}
2059 		mp->b_cont = datap;
2060 		miocack(q, mp, sizeof (int), 0);
2061 		return (B_TRUE);
2062 	}
2063 
2064 	case KIOCSDIRECT:
2065 		/*
2066 		 * Peek at this, set our variables, and then let the kbtrans
2067 		 * based code see it and respond to it.
2068 		 */
2069 		error = miocpullup(mp, sizeof (int));
2070 		if (error != 0) {
2071 			return (B_FALSE);
2072 		}
2073 
2074 		directio = *(int *)mp->b_cont->b_rptr;
2075 		if (directio != 0 && directio != 1) {
2076 			miocnak(q, mp, 0, EINVAL);
2077 			return (B_TRUE);
2078 		}
2079 		conskbd.conskbd_directio = directio;
2080 
2081 		if (conskbd.conskbd_directio) {
2082 			kbtrans_streams_set_queue(
2083 			    conskbd.conskbd_kbtrans, conskbd_regqueue);
2084 		} else {
2085 			kbtrans_streams_set_queue(
2086 			    conskbd.conskbd_kbtrans, conskbd_consqueue);
2087 		}
2088 
2089 		/*
2090 		 * Let the kbtrans-based code see this and respond to it.
2091 		 */
2092 		return (B_FALSE);
2093 
2094 	default:
2095 		return (B_FALSE);
2096 	}
2097 
2098 }	/* conskbd_override_kbtrans() */
2099 
2100 
2101 static void
2102 conskbd_polledio_enter(struct cons_polledio_arg *arg)
2103 {
2104 	conskbd_state_t		*conskbdp;
2105 	struct cons_polledio		*cb;
2106 	conskbd_lower_queue_t	*lqs;
2107 
2108 	conskbdp = (conskbd_state_t *)arg;
2109 	for (lqs = conskbdp->conskbd_lqueue_list; lqs; lqs = lqs->lqs_next) {
2110 		cb = lqs->lqs_polledio;
2111 		if ((cb != NULL) && (cb->cons_polledio_enter != NULL)) {
2112 			cb->cons_polledio_enter(cb->cons_polledio_argument);
2113 		}
2114 	}
2115 
2116 }	/* conskbd_polledio_enter() */
2117 
2118 static void
2119 conskbd_polledio_exit(struct cons_polledio_arg *arg)
2120 {
2121 	conskbd_state_t		*conskbdp;
2122 	struct cons_polledio		*cb;
2123 	conskbd_lower_queue_t	*lqs;
2124 
2125 	conskbdp = (conskbd_state_t *)arg;
2126 	for (lqs = conskbdp->conskbd_lqueue_list; lqs; lqs = lqs->lqs_next) {
2127 		cb = lqs->lqs_polledio;
2128 		if ((cb != NULL) && (cb->cons_polledio_exit != NULL)) {
2129 			cb->cons_polledio_exit(cb->cons_polledio_argument);
2130 		}
2131 	}
2132 
2133 }	/* conskbd_polledio_exit() */
2134 
2135 static int
2136 conskbd_polledio_getchar(struct cons_polledio_arg *arg)
2137 {
2138 	conskbd_state_t  *conskbdp;
2139 
2140 	conskbdp = (conskbd_state_t *)arg;
2141 
2142 	return (kbtrans_getchar(conskbdp->conskbd_kbtrans));
2143 
2144 }	/* conskbd_polledio_getchar() */
2145 
2146 static int
2147 conskbd_polledio_ischar(struct cons_polledio_arg *arg)
2148 {
2149 	conskbd_state_t  *conskbdp;
2150 
2151 	conskbdp = (conskbd_state_t *)arg;
2152 
2153 	return (kbtrans_ischar(conskbdp->conskbd_kbtrans));
2154 
2155 }	/* conskbd_polledio_ischar() */
2156 
2157 
2158 static void
2159 conskbd_mux_enqueue_msg(conskbd_pending_msg_t *msg)
2160 {
2161 	mutex_enter(&conskbd_msgq_lock);
2162 	msg->kpm_next = conskbd_msg_queue;
2163 	conskbd_msg_queue = msg;
2164 	mutex_exit(&conskbd_msgq_lock);
2165 
2166 }	/* conskbd_mux_enqueue_msg() */
2167 
2168 /*
2169  * the messages in conskbd_msg_queue we just enqueue
2170  */
2171 static conskbd_pending_msg_t *
2172 conskbd_mux_find_msg(mblk_t *mp)
2173 {
2174 	conskbd_pending_msg_t	*msg;
2175 	struct iocblk		*iocp;
2176 	uint_t	id;
2177 
2178 	mutex_enter(&conskbd_msgq_lock);
2179 	msg = conskbd_msg_queue;
2180 
2181 	iocp = (struct iocblk *)mp->b_rptr;
2182 	ASSERT(iocp);
2183 	id = iocp->ioc_id;
2184 	while (msg && msg->kpm_req_id != id) {
2185 		msg = msg->kpm_next;
2186 	}
2187 	mutex_exit(&conskbd_msgq_lock);
2188 
2189 	return (msg);
2190 
2191 }	/* conskbd_mux_find_msg() */
2192 
2193 
2194 static void
2195 conskbd_mux_dequeue_msg(conskbd_pending_msg_t *msg)
2196 {
2197 	conskbd_pending_msg_t *prev;
2198 	conskbd_pending_msg_t *p;
2199 
2200 	mutex_enter(&conskbd_msgq_lock);
2201 	prev = conskbd_msg_queue;
2202 
2203 	for (p = prev; p != msg; p = p->kpm_next)
2204 		prev = p;
2205 	ASSERT(p && p == msg);
2206 	if (prev == p) {
2207 		conskbd_msg_queue = msg->kpm_next;
2208 	} else {
2209 		prev->kpm_next = p->kpm_next;
2210 	}
2211 	p->kpm_next = NULL;
2212 	mutex_exit(&conskbd_msgq_lock);
2213 
2214 }	/* conskbd_mux_dequeue_msg() */
2215 
2216 #ifdef DEBUG
2217 /*ARGSUSED*/
2218 void
2219 conskbd_dprintf(const char *fmt, ...)
2220 {
2221 	char buf[256];
2222 	va_list ap;
2223 
2224 	va_start(ap, fmt);
2225 	(void) vsprintf(buf, fmt, ap);
2226 	va_end(ap);
2227 
2228 	cmn_err(CE_CONT, "conskbd: %s", buf);
2229 
2230 }	/* conskbd_dprintf() */
2231 #endif
2232