xref: /illumos-gate/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c (revision 3bb8546d907194e91bea367d863eb10ce3fe6621)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * USB keyboard input streams module - processes USB keypacket
29  * received from HID driver below to either ASCII or event
30  * format for windowing system.
31  */
32 #include <sys/usb/usba/usbai_version.h>
33 
34 #define	KEYMAP_SIZE_VARIABLE
35 #include <sys/usb/usba.h>
36 #include <sys/usb/clients/hid/hid.h>
37 #include <sys/usb/clients/hid/hid_polled.h>
38 #include <sys/usb/clients/hidparser/hidparser.h>
39 #include <sys/stropts.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
42 #include <sys/kbio.h>
43 #include <sys/vuid_event.h>
44 #include <sys/kbd.h>
45 #include <sys/consdev.h>
46 #include <sys/kbtrans.h>
47 #include <sys/usb/clients/usbkbm/usbkbm.h>
48 #include <sys/beep.h>
49 #include <sys/inttypes.h>
50 
51 /* debugging information */
52 uint_t	usbkbm_errmask = (uint_t)PRINT_MASK_ALL;
53 uint_t	usbkbm_errlevel = USB_LOG_L2;
54 static usb_log_handle_t usbkbm_log_handle;
55 
56 typedef void (*process_key_callback_t)(usbkbm_state_t *, int, enum keystate);
57 
58 /*
59  * Internal Function Prototypes
60  */
61 static void usbkbm_streams_setled(struct kbtrans_hardware *, int);
62 static void usbkbm_polled_setled(struct kbtrans_hardware *, int);
63 static boolean_t usbkbm_polled_keycheck(struct kbtrans_hardware *,
64 			int *, enum keystate *);
65 static void usbkbm_poll_callback(usbkbm_state_t *, int, enum keystate);
66 static void usbkbm_streams_callback(usbkbm_state_t *, int, enum keystate);
67 static void usbkbm_unpack_usb_packet(usbkbm_state_t *, process_key_callback_t,
68 			uchar_t *);
69 static boolean_t usbkbm_is_modkey(uchar_t);
70 static void usbkbm_reioctl(void	*);
71 static int usbkbm_polled_getchar(cons_polledio_arg_t);
72 static boolean_t usbkbm_polled_ischar(cons_polledio_arg_t);
73 static void usbkbm_polled_enter(cons_polledio_arg_t);
74 static void usbkbm_polled_exit(cons_polledio_arg_t);
75 static void usbkbm_mctl_receive(queue_t *, mblk_t *);
76 static enum kbtrans_message_response usbkbm_ioctl(queue_t *, mblk_t *);
77 static int usbkbm_kioccmd(usbkbm_state_t *, mblk_t *, char, size_t *);
78 static void	usbkbm_usb2pc_xlate(usbkbm_state_t *, int, enum keystate);
79 static void	usbkbm_wrap_kbtrans(usbkbm_state_t *, int, enum keystate);
80 static int	usbkbm_get_input_format(usbkbm_state_t *);
81 static int	usbkbm_get_vid_pid(usbkbm_state_t *);
82 
83 /* stream qinit functions defined here */
84 static int	usbkbm_open(queue_t *, dev_t *, int, int, cred_t *);
85 static int	usbkbm_close(queue_t *, int, cred_t *);
86 static int	usbkbm_wput(queue_t *, mblk_t *);
87 static int	usbkbm_rput(queue_t *, mblk_t *);
88 static ushort_t	usbkbm_get_state(usbkbm_state_t *);
89 static void	usbkbm_get_scancode(usbkbm_state_t *, int *, enum keystate *);
90 
91 static struct keyboard *usbkbm_keyindex;
92 
93 /* External Functions */
94 extern void space_free(char *);
95 extern uintptr_t space_fetch(char *);
96 extern int space_store(char *, uintptr_t);
97 extern struct keyboard *kbtrans_usbkb_maptab_init(void);
98 extern void kbtrans_usbkb_maptab_fini(struct keyboard **);
99 extern keymap_entry_t kbtrans_keycode_usb2pc(int);
100 
101 /*
102  * Structure to setup callbacks
103  */
104 struct kbtrans_callbacks kbd_usb_callbacks = {
105 	usbkbm_streams_setled,
106 	usbkbm_polled_setled,
107 	usbkbm_polled_keycheck,
108 };
109 
110 /*
111  * Global Variables
112  */
113 
114 /* This variable saves the LED state across hotplugging. */
115 static uchar_t	usbkbm_led_state = 0;
116 
117 /* This variable saves the layout state */
118 static uint16_t usbkbm_layout = 0;
119 
120 /*
121  * Function pointer array for mapping of scancodes.
122  */
123 void (*usbkbm_xlate[2])(usbkbm_state_t *, int, enum keystate) = {
124 	usbkbm_wrap_kbtrans,
125 	usbkbm_usb2pc_xlate
126 };
127 
128 static struct streamtab usbkbm_info;
129 static struct fmodsw fsw = {
130 	"usbkbm",
131 	&usbkbm_info,
132 	D_MP | D_MTPERMOD
133 };
134 
135 
136 /*
137  * Module linkage information for the kernel.
138  */
139 static struct modlstrmod modlstrmod = {
140 	&mod_strmodops,
141 	"USB keyboard streams 1.44",
142 	&fsw
143 };
144 
145 static struct modlinkage modlinkage = {
146 	MODREV_1,
147 	(void *)&modlstrmod,
148 	NULL
149 };
150 
151 
152 int
153 _init(void)
154 {
155 	int	rval = mod_install(&modlinkage);
156 	usbkbm_save_state_t *sp;
157 
158 	if (rval != 0) {
159 
160 		return (rval);
161 	}
162 
163 	usbkbm_keyindex = kbtrans_usbkb_maptab_init();
164 
165 	usbkbm_log_handle = usb_alloc_log_hdl(NULL, "usbkbm",
166 	    &usbkbm_errlevel, &usbkbm_errmask, NULL, 0);
167 
168 	sp = (usbkbm_save_state_t *)space_fetch("SUNW,usbkbm_state");
169 
170 	if (sp == NULL) {
171 
172 		return (0);
173 	}
174 
175 	/* Restore LED information */
176 	usbkbm_led_state = sp->usbkbm_save_led;
177 
178 	/* Restore the Layout */
179 	usbkbm_layout = sp->usbkbm_layout;
180 
181 	/* Restore abort information */
182 	usbkbm_keyindex->k_abort1 =
183 	    sp->usbkbm_save_keyindex.k_abort1;
184 
185 	usbkbm_keyindex->k_abort2 =
186 	    sp->usbkbm_save_keyindex.k_abort2;
187 
188 	usbkbm_keyindex->k_newabort1 =
189 	    sp->usbkbm_save_keyindex.k_newabort1;
190 
191 	usbkbm_keyindex->k_newabort2 =
192 	    sp->usbkbm_save_keyindex.k_newabort2;
193 
194 	/* Restore keytables */
195 	bcopy(sp->usbkbm_save_keyindex.k_normal,
196 	    usbkbm_keyindex->k_normal, USB_KEYTABLE_SIZE);
197 
198 	bcopy(sp->usbkbm_save_keyindex.k_shifted,
199 	    usbkbm_keyindex->k_shifted, USB_KEYTABLE_SIZE);
200 
201 	bcopy(sp->usbkbm_save_keyindex.k_caps,
202 	    usbkbm_keyindex->k_caps, USB_KEYTABLE_SIZE);
203 
204 	bcopy(sp->usbkbm_save_keyindex.k_altgraph,
205 	    usbkbm_keyindex->k_altgraph, USB_KEYTABLE_SIZE);
206 
207 	bcopy(sp->usbkbm_save_keyindex.k_numlock,
208 	    usbkbm_keyindex->k_numlock, USB_KEYTABLE_SIZE);
209 
210 	bcopy(sp->usbkbm_save_keyindex.k_control,
211 	    usbkbm_keyindex->k_control, USB_KEYTABLE_SIZE);
212 
213 	bcopy(sp->usbkbm_save_keyindex.k_up,
214 	    usbkbm_keyindex->k_up, USB_KEYTABLE_SIZE);
215 
216 	kmem_free(sp->usbkbm_save_keyindex.k_normal,
217 	    USB_KEYTABLE_SIZE);
218 	kmem_free(sp->usbkbm_save_keyindex.k_shifted,
219 	    USB_KEYTABLE_SIZE);
220 	kmem_free(sp->usbkbm_save_keyindex.k_caps,
221 	    USB_KEYTABLE_SIZE);
222 	kmem_free(sp->usbkbm_save_keyindex.k_altgraph,
223 	    USB_KEYTABLE_SIZE);
224 	kmem_free(sp->usbkbm_save_keyindex.k_numlock,
225 	    USB_KEYTABLE_SIZE);
226 	kmem_free(sp->usbkbm_save_keyindex.k_control,
227 	    USB_KEYTABLE_SIZE);
228 	kmem_free(sp->usbkbm_save_keyindex.k_up,
229 	    USB_KEYTABLE_SIZE);
230 
231 	kmem_free(sp, sizeof (usbkbm_save_state_t));
232 	space_free("SUNW,usbkbm_state");
233 
234 	return (0);
235 }
236 
237 int
238 _fini(void)
239 {
240 	usbkbm_save_state_t *sp;
241 	int sval;
242 	int rval;
243 
244 	sp = kmem_alloc(sizeof (usbkbm_save_state_t), KM_SLEEP);
245 	sval = space_store("SUNW,usbkbm_state", (uintptr_t)sp);
246 
247 	/*
248 	 * If it's not possible to store the state, return
249 	 * EBUSY.
250 	 */
251 	if (sval != 0) {
252 		kmem_free(sp, sizeof (usbkbm_save_state_t));
253 
254 		return (EBUSY);
255 	}
256 
257 	rval = mod_remove(&modlinkage);
258 
259 	if (rval != 0) {
260 		kmem_free(sp, sizeof (usbkbm_save_state_t));
261 		space_free("SUNW,usbkbm_state");
262 
263 		return (rval);
264 	}
265 
266 	usb_free_log_hdl(usbkbm_log_handle);
267 
268 	/* Save the LED state */
269 	sp->usbkbm_save_led = usbkbm_led_state;
270 
271 	/* Save the layout */
272 	sp->usbkbm_layout = (uchar_t)usbkbm_layout;
273 
274 	/*
275 	 * Save entries of the keyboard structure that
276 	 * have changed.
277 	 */
278 	sp->usbkbm_save_keyindex.k_abort1 = usbkbm_keyindex->k_abort1;
279 	sp->usbkbm_save_keyindex.k_abort2 = usbkbm_keyindex->k_abort2;
280 
281 	sp->usbkbm_save_keyindex.k_newabort1 = usbkbm_keyindex->k_newabort1;
282 	sp->usbkbm_save_keyindex.k_newabort2 = usbkbm_keyindex->k_newabort2;
283 
284 	/* Allocate space for keytables to be stored */
285 	sp->usbkbm_save_keyindex.k_normal =
286 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
287 	sp->usbkbm_save_keyindex.k_shifted =
288 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
289 	sp->usbkbm_save_keyindex.k_caps =
290 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
291 	sp->usbkbm_save_keyindex.k_altgraph =
292 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
293 	sp->usbkbm_save_keyindex.k_numlock =
294 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
295 	sp->usbkbm_save_keyindex.k_control =
296 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
297 	sp->usbkbm_save_keyindex.k_up =
298 	    kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
299 
300 	/* Copy over the keytables */
301 	bcopy(usbkbm_keyindex->k_normal,
302 	    sp->usbkbm_save_keyindex.k_normal, USB_KEYTABLE_SIZE);
303 
304 	bcopy(usbkbm_keyindex->k_shifted,
305 	    sp->usbkbm_save_keyindex.k_shifted, USB_KEYTABLE_SIZE);
306 
307 	bcopy(usbkbm_keyindex->k_caps,
308 	    sp->usbkbm_save_keyindex.k_caps, USB_KEYTABLE_SIZE);
309 
310 	bcopy(usbkbm_keyindex->k_altgraph,
311 	    sp->usbkbm_save_keyindex.k_altgraph, USB_KEYTABLE_SIZE);
312 
313 	bcopy(usbkbm_keyindex->k_numlock,
314 	    sp->usbkbm_save_keyindex.k_numlock, USB_KEYTABLE_SIZE);
315 
316 	bcopy(usbkbm_keyindex->k_control,
317 	    sp->usbkbm_save_keyindex.k_control, USB_KEYTABLE_SIZE);
318 
319 	bcopy(usbkbm_keyindex->k_up,
320 	    sp->usbkbm_save_keyindex.k_up, USB_KEYTABLE_SIZE);
321 
322 	kbtrans_usbkb_maptab_fini(&usbkbm_keyindex);
323 
324 	return (0);
325 }
326 
327 int
328 _info(struct modinfo *modinfop)
329 {
330 	return (mod_info(&modlinkage, modinfop));
331 }
332 
333 /*
334  * Module qinit functions
335  */
336 
337 static struct module_info usbkbm_minfo = {
338 	0,		/* module id number */
339 	"usbkbm",	/* module name */
340 	0,		/* min packet size accepted */
341 	INFPSZ,		/* max packet size accepted */
342 	2048,		/* hi-water mark */
343 	128		/* lo-water mark */
344 	};
345 
346 /* read side for key data and ioctl replies */
347 static struct qinit usbkbm_rinit = {
348 	usbkbm_rput,
349 	NULL,		/* service not used */
350 	usbkbm_open,
351 	usbkbm_close,
352 	NULL,
353 	&usbkbm_minfo
354 	};
355 
356 /* write side for ioctls */
357 static struct qinit usbkbm_winit = {
358 	usbkbm_wput,
359 	NULL,
360 	usbkbm_open,
361 	usbkbm_close,
362 	NULL,
363 	&usbkbm_minfo
364 	};
365 
366 static struct streamtab usbkbm_info = {
367 	&usbkbm_rinit,
368 	&usbkbm_winit,
369 	NULL,		/* for muxes */
370 	NULL,		/* for muxes */
371 };
372 
373 /*
374  * usbkbm_open :
375  *	Open a keyboard
376  */
377 /* ARGSUSED */
378 static int
379 usbkbm_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
380 {
381 	usbkbm_state_t	*usbkbmd;
382 	struct iocblk	mctlmsg;
383 	mblk_t		*mctl_ptr;
384 	uintptr_t	abortable = (uintptr_t)B_TRUE;
385 	int		error, ret;
386 
387 	if (q->q_ptr) {
388 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
389 		    "usbkbm_open already opened");
390 
391 		return (0); /* already opened */
392 	}
393 
394 	switch (sflag) {
395 
396 	case MODOPEN:
397 		break;
398 
399 	case CLONEOPEN:
400 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
401 		    "usbkbm_open: Clone open not supported");
402 
403 		/* FALLTHRU */
404 	default:
405 
406 		return (EINVAL);
407 	}
408 
409 	/* allocate usb keyboard state structure */
410 
411 	usbkbmd = kmem_zalloc(sizeof (usbkbm_state_t), KM_SLEEP);
412 
413 	USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
414 	    "usbkbm_state= %p", (void *)usbkbmd);
415 
416 	/*
417 	 * Set up private data.
418 	 */
419 	usbkbmd->usbkbm_readq = q;
420 	usbkbmd->usbkbm_writeq = WR(q);
421 
422 	usbkbmd->usbkbm_vkbd_type = KB_USB;
423 	/*
424 	 * Set up queue pointers, so that the "put" procedure will accept
425 	 * the reply to the "ioctl" message we send down.
426 	 */
427 	q->q_ptr = (caddr_t)usbkbmd;
428 	WR(q)->q_ptr = (caddr_t)usbkbmd;
429 
430 	error = kbtrans_streams_init(q, sflag,
431 	    (struct kbtrans_hardware *)usbkbmd, &kbd_usb_callbacks,
432 	    &usbkbmd->usbkbm_kbtrans, usbkbm_led_state, 0);
433 
434 	if (error != 0) {
435 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
436 		    "kbdopen:  kbtrans_streams_init failed\n");
437 		kmem_free(usbkbmd, sizeof (*usbkbmd));
438 
439 		return (error);
440 	}
441 
442 	/*
443 	 * Set the polled information in the state structure.
444 	 * This information is set once, and doesn't change
445 	 */
446 	usbkbmd->usbkbm_polled_info.cons_polledio_version =
447 	    CONSPOLLEDIO_V1;
448 
449 	usbkbmd->usbkbm_polled_info.cons_polledio_argument =
450 	    (cons_polledio_arg_t)usbkbmd;
451 
452 	usbkbmd->usbkbm_polled_info.cons_polledio_putchar = NULL;
453 
454 	usbkbmd->usbkbm_polled_info.cons_polledio_getchar =
455 	    usbkbm_polled_getchar;
456 
457 	usbkbmd->usbkbm_polled_info.cons_polledio_ischar =
458 	    usbkbm_polled_ischar;
459 
460 	usbkbmd->usbkbm_polled_info.cons_polledio_enter =
461 	    usbkbm_polled_enter;
462 
463 	usbkbmd->usbkbm_polled_info.cons_polledio_exit =
464 	    usbkbm_polled_exit;
465 
466 	usbkbmd->usbkbm_polled_info.cons_polledio_setled =
467 	    (void (*)(cons_polledio_arg_t, int))usbkbm_polled_setled;
468 
469 	usbkbmd->usbkbm_polled_info.cons_polledio_keycheck =
470 	    (boolean_t (*)(cons_polledio_arg_t, int *,
471 	    enum keystate *))usbkbm_polled_keycheck;
472 	/*
473 	 * The head and the tail pointing at the same byte means empty or
474 	 * full. usbkbm_polled_buffer_num_characters is used to
475 	 * tell the difference.
476 	 */
477 	usbkbmd->usbkbm_polled_buffer_head =
478 	    usbkbmd->usbkbm_polled_scancode_buffer;
479 	usbkbmd->usbkbm_polled_buffer_tail =
480 	    usbkbmd->usbkbm_polled_scancode_buffer;
481 	usbkbmd->usbkbm_polled_buffer_num_characters = 0;
482 
483 	qprocson(q);
484 
485 	/* request hid report descriptor from HID */
486 	mctlmsg.ioc_cmd = HID_GET_PARSER_HANDLE;
487 	mctlmsg.ioc_count = 0;
488 	mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
489 	if (mctl_ptr == NULL) {
490 		/* failure to allocate M_CTL message */
491 		(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
492 		qprocsoff(q);
493 		kmem_free(usbkbmd, sizeof (*usbkbmd));
494 
495 		return (ENOMEM);
496 	}
497 
498 	/* send message to hid */
499 	putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
500 
501 	/*
502 	 * Now that M_CTL has been sent, wait for report descriptor.  Cleanup
503 	 * if user signals in the mean time (as when this gets opened in an
504 	 * inappropriate context and the user types a ^C).
505 	 */
506 	usbkbmd->usbkbm_flags |= USBKBM_QWAIT;
507 	while (usbkbmd->usbkbm_flags & USBKBM_QWAIT) {
508 
509 		if (qwait_sig(q) == 0) {
510 			usbkbmd->usbkbm_flags = 0;
511 			(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
512 			qprocsoff(q);
513 			kmem_free(usbkbmd, sizeof (*usbkbmd));
514 
515 			return (EINTR);
516 		}
517 	}
518 
519 
520 	/* get the input format from the hid descriptor */
521 	if (usbkbm_get_input_format(usbkbmd) != USB_SUCCESS) {
522 
523 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
524 		    "usbkbm: Invalid HID Descriptor Tree."
525 		    "setting default report format");
526 	}
527 
528 	/*
529 	 * Although Sun Japanese type6 and type7 keyboards have the same
530 	 * layout number(15), they should be recognized for loading the
531 	 * different keytables on upper apps (e.g. X). The new layout
532 	 * number (271) is defined for the Sun Japanese type6 keyboards.
533 	 * The layout number (15) specified in HID spec is used for other
534 	 * Japanese keyboards. It is a workaround for the old Sun Japanese
535 	 * type6 keyboards defect.
536 	 */
537 	if (usbkbmd->usbkbm_layout == SUN_JAPANESE_TYPE7) {
538 
539 		if ((ret = usbkbm_get_vid_pid(usbkbmd)) != 0) {
540 
541 			return (ret);
542 		}
543 
544 		if ((usbkbmd->usbkbm_vid_pid.VendorId ==
545 		    HID_SUN_JAPANESE_TYPE6_KBD_VID) &&
546 		    (usbkbmd->usbkbm_vid_pid.ProductId ==
547 		    HID_SUN_JAPANESE_TYPE6_KBD_PID)) {
548 			usbkbmd->usbkbm_layout = SUN_JAPANESE_TYPE6;
549 		}
550 	}
551 
552 	kbtrans_streams_set_keyboard(usbkbmd->usbkbm_kbtrans, KB_USB,
553 	    usbkbm_keyindex);
554 
555 	usbkbmd->usbkbm_flags = USBKBM_OPEN;
556 
557 	kbtrans_streams_enable(usbkbmd->usbkbm_kbtrans);
558 
559 	/*
560 	 * Enable abort sequence on inital. For an internal open, conskbd
561 	 * will disable driver abort handling (later through M_IOCTL) and
562 	 * handle it by itself.
563 	 * For an external (aka. physical) open, this is necessary since
564 	 * no STREAMS module linked on top of usbkbm handles abort sequence.
565 	 */
566 	mctlmsg.ioc_cmd = CONSSETABORTENABLE;
567 	mctlmsg.ioc_count = TRANSPARENT;
568 	mctl_ptr = usba_mk_mctl(mctlmsg, &abortable, sizeof (abortable));
569 	if (mctl_ptr != NULL) {
570 		DB_TYPE(mctl_ptr) = M_IOCTL;
571 		if (kbtrans_streams_message(usbkbmd->usbkbm_kbtrans, mctl_ptr)
572 		    != KBTRANS_MESSAGE_HANDLED) {
573 			freemsg(mctl_ptr);
574 		}
575 	} else {
576 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
577 		    "usbkbm: enable abort sequence failed");
578 	}
579 
580 	USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
581 	    "usbkbm_open exiting");
582 	return (0);
583 }
584 
585 
586 /*
587  * usbkbm_close :
588  *	Close a keyboard.
589  */
590 /* ARGSUSED1 */
591 static int
592 usbkbm_close(register queue_t *q, int flag, cred_t *crp)
593 {
594 	usbkbm_state_t *usbkbmd = (usbkbm_state_t *)q->q_ptr;
595 
596 	/* If a beep is in progress, stop that */
597 	(void) beeper_off();
598 
599 	(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
600 
601 	qprocsoff(q);
602 	/*
603 	 * Since we're about to destroy our private data, turn off
604 	 * our open flag first, so we don't accept any more input
605 	 * and try to use that data.
606 	 */
607 	usbkbmd->usbkbm_flags = 0;
608 
609 	kmem_free(usbkbmd, sizeof (usbkbm_state_t));
610 
611 	USB_DPRINTF_L3(PRINT_MASK_CLOSE, usbkbm_log_handle,
612 	    "usbkbm_close exiting");
613 
614 	return (0);
615 }
616 
617 
618 /*
619  * usbkbm_wput :
620  *	usb keyboard module output queue put procedure: handles M_IOCTL
621  *	messages.
622  */
623 static int
624 usbkbm_wput(register queue_t *q, register mblk_t *mp)
625 {
626 	usbkbm_state_t			*usbkbmd;
627 	enum kbtrans_message_response	ret;
628 
629 	USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
630 	    "usbkbm_wput entering");
631 
632 	usbkbmd = (usbkbm_state_t *)q->q_ptr;
633 
634 	/* First, see if kbtrans will handle the message */
635 	ret = kbtrans_streams_message(usbkbmd->usbkbm_kbtrans, mp);
636 
637 	if (ret == KBTRANS_MESSAGE_HANDLED) {
638 
639 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
640 		    "usbkbm_wput exiting:2");
641 
642 		return (0);
643 	}
644 
645 	/* kbtrans didn't handle the message.  Try to handle it here */
646 
647 	switch (mp->b_datap->db_type) {
648 
649 	case M_FLUSH:
650 		if (*mp->b_rptr & FLUSHW) {
651 			flushq(q, FLUSHDATA);
652 		}
653 
654 		if (*mp->b_rptr & FLUSHR) {
655 			flushq(RD(q), FLUSHDATA);
656 		}
657 
658 		break;
659 
660 	case M_IOCTL:
661 		ret = usbkbm_ioctl(q, mp);
662 
663 		if (ret == KBTRANS_MESSAGE_HANDLED) {
664 
665 			USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
666 			    "usbkbm_wput exiting:1");
667 
668 			return (0);
669 		}
670 	default:
671 		break;
672 	}
673 
674 	/*
675 	 * The message has not been handled
676 	 * by kbtrans or this module.  Pass it down the stream
677 	 */
678 	putnext(q, mp);
679 
680 	USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
681 	    "usbkbm_wput exiting:3");
682 	return (0);
683 }
684 
685 /*
686  * usbkbm_ioctl :
687  *	Handles the ioctls sent from upper module. Returns
688  *	ACK/NACK back.
689  */
690 static enum kbtrans_message_response
691 usbkbm_ioctl(register queue_t *q, register mblk_t *mp)
692 {
693 	usbkbm_state_t		*usbkbmd;
694 	struct iocblk		mctlmsg;
695 	struct iocblk		*iocp;
696 	mblk_t			*datap, *mctl_ptr;
697 	size_t			ioctlrespsize;
698 	int			err;
699 	int			tmp;
700 	int			cycles;
701 	int			frequency;
702 	int			msecs;
703 	char			command;
704 
705 	err = 0;
706 
707 	usbkbmd = (usbkbm_state_t *)q->q_ptr;
708 	iocp = (struct iocblk *)mp->b_rptr;
709 
710 	switch (iocp->ioc_cmd) {
711 	case CONSSETKBDTYPE:
712 		err = miocpullup(mp, sizeof (int));
713 		if (err != 0) {
714 			break;
715 		}
716 		tmp = *(int *)mp->b_cont->b_rptr;
717 		if (tmp != KB_PC && tmp != KB_USB) {
718 			err = EINVAL;
719 			break;
720 		}
721 		usbkbmd->usbkbm_vkbd_type = tmp;
722 		break;
723 	case KIOCLAYOUT:
724 
725 		datap = allocb(sizeof (int), BPRI_HI);
726 		if (datap == NULL) {
727 			ioctlrespsize = sizeof (int);
728 
729 			goto allocfailure;
730 		}
731 
732 		*(int *)datap->b_wptr = usbkbmd->usbkbm_layout;
733 		datap->b_wptr += sizeof (int);
734 
735 		freemsg(mp->b_cont);
736 
737 		mp->b_cont = datap;
738 		iocp->ioc_count = sizeof (int);
739 		break;
740 
741 	case KIOCSLAYOUT:
742 		/*
743 		 * Supply a layout if not specified by the hardware, or
744 		 * override any that was specified.
745 		 */
746 		if (iocp->ioc_count != TRANSPARENT) {
747 			err = EINVAL;
748 			break;
749 		}
750 
751 		usbkbmd->usbkbm_layout = *(intptr_t *)mp->b_cont->b_rptr;
752 
753 		/*
754 		 * Save the layout in usbkbm_layout so as to handle the
755 		 * the case when the user has re-plugged in the non-self
756 		 * identifying non US keyboard. In this the layout is saved
757 		 * in global variable, so the user does not have to run
758 		 * kdmconfig again after the X server reset
759 		 */
760 
761 		usbkbm_layout = usbkbmd->usbkbm_layout;
762 		break;
763 
764 	case KIOCCMD:
765 		/*
766 		 * Check if we have at least the subcommand field; any
767 		 * other argument validation has to occur inside
768 		 * usbkbm_kioccmd().
769 		 */
770 		err = miocpullup(mp, sizeof (int));
771 		if (err != 0)
772 			break;
773 
774 		/* Subcommand */
775 		command = (char)(*(int *)mp->b_cont->b_rptr);
776 
777 		/*
778 		 * Check if this ioctl is followed by a previous
779 		 * KBD_CMD_SETLED command, in which case we take
780 		 * the command byte as the data for setting the LED
781 		 */
782 		if (usbkbmd->usbkbm_setled_second_byte) {
783 			usbkbm_streams_setled((struct kbtrans_hardware *)
784 			    usbkbmd, command);
785 			usbkbmd->usbkbm_setled_second_byte = 0;
786 			break;
787 		}
788 
789 		/*
790 		 * In  case of allocb failure, this will
791 		 * return the size of the allocation which
792 		 * failed so that it can be allocated later
793 		 * through bufcall.
794 		 */
795 		ioctlrespsize = 0;
796 
797 		err = usbkbm_kioccmd(usbkbmd, mp, command, &ioctlrespsize);
798 
799 		if (ioctlrespsize != 0) {
800 
801 			goto allocfailure;
802 		}
803 
804 		break;
805 
806 	case CONSOPENPOLLEDIO:
807 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
808 		    "usbkbm_ioctl CONSOPENPOLLEDIO");
809 
810 		err = miocpullup(mp, sizeof (struct cons_polledio *));
811 		if (err != 0) {
812 			USB_DPRINTF_L2(PRINT_MASK_ALL, usbkbm_log_handle,
813 			    "usbkbm_ioctl: malformed request");
814 			break;
815 		}
816 
817 		usbkbmd->usbkbm_pending_link = mp;
818 
819 		/*
820 		 * Get the polled input structure from hid
821 		 */
822 		mctlmsg.ioc_cmd = HID_OPEN_POLLED_INPUT;
823 		mctlmsg.ioc_count = 0;
824 		mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
825 		if (mctl_ptr == NULL) {
826 			ioctlrespsize = sizeof (mctlmsg);
827 
828 			goto allocfailure;
829 		}
830 
831 		putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
832 
833 		/*
834 		 * Do not ack or nack the message, we will wait for the
835 		 * result of HID_OPEN_POLLED_INPUT
836 		 */
837 
838 		return (KBTRANS_MESSAGE_HANDLED);
839 
840 	case CONSCLOSEPOLLEDIO:
841 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
842 		    "usbkbm_ioctl CONSCLOSEPOLLEDIO mp = 0x%p", (void *)mp);
843 
844 		usbkbmd->usbkbm_pending_link = mp;
845 
846 		/*
847 		 * Get the polled input structure from hid
848 		 */
849 		mctlmsg.ioc_cmd = HID_CLOSE_POLLED_INPUT;
850 		mctlmsg.ioc_count = 0;
851 		mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
852 		if (mctl_ptr == NULL) {
853 			ioctlrespsize = sizeof (mctlmsg);
854 
855 			goto allocfailure;
856 		}
857 
858 		putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
859 
860 		/*
861 		 * Do not ack or nack the message, we will wait for the
862 		 * result of HID_CLOSE_POLLED_INPUT
863 		 */
864 
865 		return (KBTRANS_MESSAGE_HANDLED);
866 
867 	case CONSSETABORTENABLE:
868 		/*
869 		 * Nothing special to do for USB.
870 		 */
871 		break;
872 
873 
874 	case KIOCMKTONE:
875 		if (iocp->ioc_count != TRANSPARENT) {
876 			err = EINVAL;
877 			break;
878 		}
879 
880 		tmp = (int)(*(intptr_t *)mp->b_cont->b_rptr);
881 		cycles = tmp & 0xffff;
882 		msecs = (tmp >> 16) & 0xffff;
883 
884 		if (cycles == 0)
885 			frequency = UINT16_MAX;
886 		else if (cycles == UINT16_MAX)
887 			frequency = 0;
888 		else {
889 			frequency = (PIT_HZ + cycles / 2) / cycles;
890 			if (frequency > UINT16_MAX)
891 				frequency = UINT16_MAX;
892 		}
893 
894 		err = beep_mktone(frequency, msecs);
895 		break;
896 
897 	default:
898 
899 		return (KBTRANS_MESSAGE_NOT_HANDLED);
900 	}
901 
902 	/*
903 	 * Send ACK/NACK to upper module for
904 	 * the messages that have been handled.
905 	 */
906 	if (err != 0) {
907 		iocp->ioc_rval = 0;
908 		iocp->ioc_error = err;
909 		mp->b_datap->db_type = M_IOCNAK;
910 	} else {
911 		iocp->ioc_rval = 0;
912 		iocp->ioc_error = 0;	/* brain rot */
913 		mp->b_datap->db_type = M_IOCACK;
914 	}
915 
916 	/* Send the response back up the stream */
917 	putnext(usbkbmd->usbkbm_readq, mp);
918 
919 	return (KBTRANS_MESSAGE_HANDLED);
920 
921 allocfailure:
922 	/*
923 	 * We needed to allocate something to handle this "ioctl", but
924 	 * couldn't; save this "ioctl" and arrange to get called back when
925 	 * it's more likely that we can get what we need.
926 	 * If there's already one being saved, throw it out, since it
927 	 * must have timed out.
928 	 */
929 	freemsg(usbkbmd->usbkbm_streams_iocpending);
930 	usbkbmd->usbkbm_streams_iocpending = mp;
931 
932 	if (usbkbmd->usbkbm_streams_bufcallid) {
933 
934 		qunbufcall(usbkbmd->usbkbm_readq,
935 		    usbkbmd->usbkbm_streams_bufcallid);
936 	}
937 	usbkbmd->usbkbm_streams_bufcallid =
938 	    qbufcall(usbkbmd->usbkbm_readq, ioctlrespsize, BPRI_HI,
939 	    usbkbm_reioctl, usbkbmd);
940 
941 	return (KBTRANS_MESSAGE_HANDLED);
942 }
943 
944 /*
945  * usbkbm_kioccmd :
946  *	Handles KIOCCMD ioctl.
947  */
948 static int
949 usbkbm_kioccmd(usbkbm_state_t *usbkbmd, register mblk_t *mp,
950     char command, size_t *ioctlrepsize)
951 {
952 	register mblk_t			*datap;
953 	register struct iocblk		*iocp;
954 	int				err = 0;
955 
956 	iocp = (struct iocblk *)mp->b_rptr;
957 
958 	switch (command) {
959 
960 		/* Keyboard layout command */
961 		case KBD_CMD_GETLAYOUT:
962 			/* layout learned at attached time. */
963 			datap = allocb(sizeof (int), BPRI_HI);
964 
965 			/* Return error  on allocation failure */
966 			if (datap == NULL) {
967 				*ioctlrepsize = sizeof (int);
968 
969 				return (EIO);
970 			}
971 
972 			*(int *)datap->b_wptr = usbkbmd->usbkbm_layout;
973 			datap->b_wptr += sizeof (int);
974 			freemsg(mp->b_cont);
975 			mp->b_cont = datap;
976 			iocp->ioc_count = sizeof (int);
977 			break;
978 
979 		case KBD_CMD_SETLED:
980 			/*
981 			 * Emulate type 4 keyboard :
982 			 * Ignore this ioctl; the following
983 			 * ioctl will specify the data byte for
984 			 * setting the LEDs; setting usbkbm_setled_second_byte
985 			 * will help recognizing that ioctl
986 			 */
987 			usbkbmd->usbkbm_setled_second_byte = 1;
988 			break;
989 
990 		case KBD_CMD_RESET:
991 			break;
992 
993 		case KBD_CMD_BELL:
994 			/*
995 			 * USB keyboards do not have a beeper
996 			 * in it, the generic beeper interface
997 			 * is used. Turn the beeper on.
998 			 */
999 			(void) beeper_on(BEEP_TYPE4);
1000 			break;
1001 
1002 		case KBD_CMD_NOBELL:
1003 			/*
1004 			 * USB keyboards do not have a beeper
1005 			 * in it, the generic beeper interface
1006 			 * is used. Turn the beeper off.
1007 			 */
1008 			(void) beeper_off();
1009 			break;
1010 
1011 		case KBD_CMD_CLICK:
1012 			/* FALLTHRU */
1013 		case KBD_CMD_NOCLICK:
1014 			break;
1015 
1016 		default:
1017 			err = EIO;
1018 			break;
1019 
1020 	}
1021 
1022 	return (err);
1023 }
1024 
1025 
1026 /*
1027  * usbkbm_rput :
1028  *	Put procedure for input from driver end of stream (read queue).
1029  */
1030 static int
1031 usbkbm_rput(register queue_t *q, register mblk_t *mp)
1032 {
1033 	usbkbm_state_t		*usbkbmd;
1034 
1035 	usbkbmd = (usbkbm_state_t *)q->q_ptr;
1036 
1037 	USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1038 	    "usbkbm_rput");
1039 
1040 	if (usbkbmd == 0) {
1041 		freemsg(mp);	/* nobody's listening */
1042 
1043 		return (0);
1044 	}
1045 
1046 	switch (mp->b_datap->db_type) {
1047 
1048 	case M_FLUSH:
1049 		if (*mp->b_rptr & FLUSHW)
1050 			flushq(WR(q), FLUSHDATA);
1051 		if (*mp->b_rptr & FLUSHR)
1052 			flushq(q, FLUSHDATA);
1053 
1054 		freemsg(mp);
1055 
1056 		return (0);
1057 	case M_BREAK:
1058 		/*
1059 		 * Will get M_BREAK only if this is not the system
1060 		 * keyboard, otherwise serial port will eat break
1061 		 * and call kmdb/OBP, without passing anything up.
1062 		 */
1063 		freemsg(mp);
1064 
1065 		return (0);
1066 	case M_DATA:
1067 		if (!(usbkbmd->usbkbm_flags & USBKBM_OPEN)) {
1068 			freemsg(mp);	/* not ready to listen */
1069 
1070 			return (0);
1071 		}
1072 
1073 		break;
1074 	case M_CTL:
1075 		usbkbm_mctl_receive(q, mp);
1076 
1077 		return (0);
1078 	case M_ERROR:
1079 		usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1080 		if (*mp->b_rptr == ENODEV) {
1081 			putnext(q, mp);
1082 		} else {
1083 			freemsg(mp);
1084 		}
1085 
1086 		return (0);
1087 	case M_IOCACK:
1088 	case M_IOCNAK:
1089 		putnext(q, mp);
1090 
1091 		return (0);
1092 	default:
1093 		putnext(q, mp);
1094 
1095 		return (0);
1096 	}
1097 
1098 	/*
1099 	 * A data message, consisting of bytes from the keyboard.
1100 	 * Ram them through the translator, only if there are
1101 	 * correct no. of bytes.
1102 	 */
1103 	if (MBLKL(mp) == usbkbmd->usbkbm_report_format.tlen) {
1104 		if (usbkbmd->usbkbm_report_format.keyid !=
1105 		    HID_REPORT_ID_UNDEFINED) {
1106 			if (*(mp->b_rptr) !=
1107 			    usbkbmd->usbkbm_report_format.keyid) {
1108 				freemsg(mp);
1109 
1110 				return (0);
1111 			} else {
1112 				/* We skip the report id prefix */
1113 				mp->b_rptr++;
1114 			}
1115 		}
1116 		usbkbm_unpack_usb_packet(usbkbmd, usbkbm_streams_callback,
1117 		    mp->b_rptr);
1118 	}
1119 
1120 	freemsg(mp);
1121 	return (0);
1122 }
1123 
1124 /*
1125  * usbkbm_mctl_receive :
1126  *	Handle M_CTL messages from hid. If we don't understand
1127  *	the command, send it up.
1128  */
1129 static void
1130 usbkbm_mctl_receive(register queue_t *q, register mblk_t *mp)
1131 {
1132 	register usbkbm_state_t *usbkbmd = (usbkbm_state_t *)q->q_ptr;
1133 	register struct iocblk *iocp;
1134 	caddr_t  data = NULL;
1135 	mblk_t	*reply_mp;
1136 	uchar_t	new_buffer[USBKBM_MAXPKTSIZE];
1137 	size_t	 size;
1138 
1139 	iocp = (struct iocblk *)mp->b_rptr;
1140 	if (mp->b_cont != NULL)
1141 		data = (caddr_t)mp->b_cont->b_rptr;
1142 
1143 	switch (iocp->ioc_cmd) {
1144 
1145 	case HID_SET_REPORT:
1146 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1147 		    "usbkbm_mctl_receive HID_SET mctl");
1148 		freemsg(mp);
1149 		/* Setting of the LED is not waiting for this message */
1150 
1151 		break;
1152 	case HID_GET_PARSER_HANDLE:
1153 		if ((data != NULL) &&
1154 		    (iocp->ioc_count == sizeof (hidparser_handle_t)) &&
1155 		    (MBLKL(mp->b_cont) == iocp->ioc_count)) {
1156 			usbkbmd->usbkbm_report_descr =
1157 			    *(hidparser_handle_t *)data;
1158 		} else {
1159 			usbkbmd->usbkbm_report_descr = NULL;
1160 		}
1161 		freemsg(mp);
1162 		usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1163 
1164 		break;
1165 	case HID_GET_VID_PID:
1166 		if ((data != NULL) &&
1167 		    (iocp->ioc_count == sizeof (hid_vid_pid_t)) &&
1168 		    (MBLKL(mp->b_cont) == iocp->ioc_count)) {
1169 			bcopy(data, &usbkbmd->usbkbm_vid_pid, iocp->ioc_count);
1170 		}
1171 		freemsg(mp);
1172 		usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1173 
1174 		break;
1175 	case HID_OPEN_POLLED_INPUT:
1176 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1177 		    "usbkbm_mctl_receive HID_OPEN_POLLED_INPUT");
1178 
1179 		size = sizeof (hid_polled_input_callback_t);
1180 		reply_mp = usbkbmd->usbkbm_pending_link;
1181 		if ((data != NULL) &&
1182 		    (iocp->ioc_count == size) &&
1183 		    (MBLKL(mp->b_cont) == size)) {
1184 			/*
1185 			 *  Copy the information from hid into the
1186 			 * state structure
1187 			 */
1188 			bcopy(data, &usbkbmd->usbkbm_hid_callback, size);
1189 			reply_mp->b_datap->db_type = M_IOCACK;
1190 
1191 			/*
1192 			 * We are given an appropriate-sized data block,
1193 			 * and return a pointer to our structure in it.
1194 			 * The structure is saved in the states structure
1195 			 */
1196 			*(cons_polledio_t **)reply_mp->b_cont->b_rptr =
1197 			    &usbkbmd->usbkbm_polled_info;
1198 
1199 		} else {
1200 			reply_mp->b_datap->db_type = M_IOCNAK;
1201 		}
1202 		freemsg(mp);
1203 
1204 		usbkbmd->usbkbm_pending_link = NULL;
1205 
1206 		putnext(q, reply_mp);
1207 
1208 		break;
1209 	case HID_CLOSE_POLLED_INPUT:
1210 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1211 		    "usbkbm_mctl_receive HID_CLOSE_POLLED_INPUT");
1212 
1213 
1214 		bzero(&usbkbmd->usbkbm_hid_callback,
1215 		    sizeof (hid_polled_input_callback_t));
1216 
1217 		freemsg(mp);
1218 
1219 		reply_mp = usbkbmd->usbkbm_pending_link;
1220 
1221 		iocp = (struct iocblk *)reply_mp->b_rptr;
1222 
1223 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1224 		    "usbkbm_mctl_receive reply reply_mp 0x%p cmd 0x%x",
1225 		    (void *)reply_mp, iocp->ioc_cmd);
1226 
1227 
1228 		reply_mp->b_datap->db_type = M_IOCACK;
1229 
1230 		usbkbmd->usbkbm_pending_link = NULL;
1231 
1232 		putnext(q, reply_mp);
1233 
1234 		break;
1235 	case HID_DISCONNECT_EVENT :
1236 	case HID_POWER_OFF:
1237 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1238 		    "usbkbm_mctl_receive HID_DISCONNECT_EVENT/HID_POWER_OFF");
1239 
1240 		/* Indicate all keys have been released */
1241 		bzero(new_buffer, USBKBM_MAXPKTSIZE);
1242 		usbkbm_unpack_usb_packet(usbkbmd, usbkbm_streams_callback,
1243 		    new_buffer);
1244 		freemsg(mp);
1245 
1246 		break;
1247 	case HID_CONNECT_EVENT:
1248 	case HID_FULL_POWER :
1249 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1250 		    "usbkbm_mctl_receive restore LEDs");
1251 
1252 		/* send setled command down to restore LED states */
1253 		usbkbm_streams_setled((struct kbtrans_hardware *)usbkbmd,
1254 		    usbkbm_led_state);
1255 
1256 		freemsg(mp);
1257 
1258 		break;
1259 	default:
1260 		putnext(q, mp);
1261 
1262 		break;
1263 	}
1264 }
1265 
1266 
1267 /*
1268  * usbkbm_streams_setled :
1269  *	Update the keyboard LEDs to match the current keyboard state.
1270  *	Send LED state downstreams to hid driver.
1271  */
1272 static void
1273 usbkbm_streams_setled(struct kbtrans_hardware *kbtrans_hw, int state)
1274 {
1275 	struct iocblk	mctlmsg;
1276 	mblk_t		*mctl_ptr;
1277 	hid_req_t	*LED_report;
1278 	usbkbm_state_t	*usbkbmd;
1279 	uchar_t		led_id, led_state;
1280 
1281 	usbkbm_led_state = (uchar_t)state;
1282 
1283 	usbkbmd = (usbkbm_state_t *)kbtrans_hw;
1284 
1285 	LED_report = kmem_zalloc(sizeof (hid_req_t), KM_NOSLEEP);
1286 	if (LED_report == NULL) {
1287 
1288 		return;
1289 	}
1290 
1291 	/*
1292 	 * Send the request to the hid driver to set LED.
1293 	 */
1294 	led_id = usbkbmd->usbkbm_report_format.keyid;
1295 	led_state = 0;
1296 
1297 	/*
1298 	 * Set the led state based on the state that is passed in.
1299 	 */
1300 	if (state & LED_NUM_LOCK) {
1301 		led_state |= USB_LED_NUM_LOCK;
1302 	}
1303 
1304 	if (state & LED_COMPOSE) {
1305 		led_state |= USB_LED_COMPOSE;
1306 	}
1307 
1308 	if (state & LED_SCROLL_LOCK) {
1309 		led_state |= USB_LED_SCROLL_LOCK;
1310 	}
1311 
1312 	if (state & LED_CAPS_LOCK) {
1313 		led_state |= USB_LED_CAPS_LOCK;
1314 	}
1315 
1316 	if (state & LED_KANA) {
1317 		led_state |= USB_LED_KANA;
1318 	}
1319 
1320 	LED_report->hid_req_version_no = HID_VERSION_V_0;
1321 	LED_report->hid_req_wValue = REPORT_TYPE_OUTPUT | led_id;
1322 	LED_report->hid_req_wLength = sizeof (uchar_t);
1323 	LED_report->hid_req_data[0] = led_state;
1324 
1325 	mctlmsg.ioc_cmd = HID_SET_REPORT;
1326 	mctlmsg.ioc_count = sizeof (LED_report);
1327 	mctl_ptr = usba_mk_mctl(mctlmsg, LED_report, sizeof (hid_req_t));
1328 	if (mctl_ptr != NULL) {
1329 		putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
1330 	}
1331 
1332 	/*
1333 	 * We are not waiting for response of HID_SET_REPORT
1334 	 * mctl for setting the LED.
1335 	 */
1336 	kmem_free(LED_report, sizeof (hid_req_t));
1337 }
1338 
1339 
1340 /*
1341  * usbkbm_polled_keycheck :
1342  *	This routine is called to determine if there is a scancode that
1343  *	is available for input.  This routine is called at poll time and
1344  *	returns a key/state pair to the caller.  If there are characters
1345  *	buffered up, the routine returns right away with the key/state pair.
1346  *	Otherwise, the routine calls down to check for characters and returns
1347  *	the first key/state pair if there are any characters pending.
1348  */
1349 static boolean_t
1350 usbkbm_polled_keycheck(struct kbtrans_hardware *hw,
1351     int *key, enum keystate *state)
1352 {
1353 	usbkbm_state_t			*usbkbmd;
1354 	uchar_t				*buffer;
1355 	unsigned			size;
1356 	hid_polled_handle_t		hid_polled_handle;
1357 
1358 	usbkbmd = (usbkbm_state_t *)hw;
1359 
1360 	/*
1361 	 * If there are already characters buffered up, then we are done.
1362 	 */
1363 	if (usbkbmd->usbkbm_polled_buffer_num_characters != 0) {
1364 
1365 		usbkbm_get_scancode(usbkbmd, key, state);
1366 
1367 		return (B_TRUE);
1368 	}
1369 
1370 	hid_polled_handle =
1371 	    usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1372 
1373 	size = (usbkbmd->usbkbm_hid_callback.hid_polled_read)
1374 	    (hid_polled_handle, &buffer);
1375 
1376 	/*
1377 	 * If we don't get a valid input report then indicate that,
1378 	 * and we are done.
1379 	 */
1380 	if (size != usbkbmd->usbkbm_report_format.tlen) {
1381 		return (B_FALSE);
1382 	}
1383 
1384 	/*
1385 	 * We have a usb packet, so pass this packet to
1386 	 * usbkbm_unpack_usb_packet so that it can be broken up into
1387 	 * individual key/state values.
1388 	 */
1389 	if (usbkbmd->usbkbm_report_format.keyid != HID_REPORT_ID_UNDEFINED) {
1390 		if (*buffer != usbkbmd->usbkbm_report_format.keyid) {
1391 			return (B_FALSE);
1392 		} else {
1393 			/* We skip the report id prefix */
1394 			buffer++;
1395 		}
1396 	}
1397 	usbkbm_unpack_usb_packet(usbkbmd, usbkbm_poll_callback, buffer);
1398 
1399 	/*
1400 	 * If a scancode was returned as a result of this packet,
1401 	 * then translate the scancode.
1402 	 */
1403 	if (usbkbmd->usbkbm_polled_buffer_num_characters != 0) {
1404 
1405 		usbkbm_get_scancode(usbkbmd, key, state);
1406 
1407 		return (B_TRUE);
1408 	}
1409 
1410 	return (B_FALSE);
1411 }
1412 
1413 static ushort_t	usbkbm_get_state(usbkbm_state_t *usbkbmd)
1414 {
1415 	ushort_t	ret;
1416 
1417 	ASSERT(usbkbmd->usbkbm_vkbd_type == KB_PC ||
1418 	    usbkbmd->usbkbm_vkbd_type == KB_USB);
1419 
1420 	if (usbkbmd->usbkbm_vkbd_type == KB_PC)
1421 		ret = INDEXTO_PC;
1422 	else
1423 		ret = INDEXTO_USB;
1424 
1425 	return (ret);
1426 }
1427 /*
1428  * usbkbm_streams_callback :
1429  *	This is the routine that is going to be called when unpacking
1430  *	usb packets for normal streams-based input.  We pass a pointer
1431  *	to this routine to usbkbm_unpack_usb_packet.  This routine will
1432  *	get called with an unpacked key (scancode) and state (press/release).
1433  *	We pass it to the generic keyboard module.
1434  *
1435  *	'index' and the function pointers:
1436  *	Map USB scancodes to PC scancodes by lookup table.
1437  *	This fix is mainly meant for x86 platforms. For SPARC systems
1438  *	this fix doesn't change the way in which the scancodes are processed.
1439  */
1440 static void
1441 usbkbm_streams_callback(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1442 {
1443 	ushort_t index = usbkbm_get_state(usbkbmd);
1444 	(*usbkbm_xlate[index])(usbkbmd, key, state);
1445 }
1446 
1447 /*
1448  * Don't do any translations. Send to 'kbtrans' for processing.
1449  */
1450 static void
1451 usbkbm_wrap_kbtrans(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1452 {
1453 	kbtrans_streams_key(usbkbmd->usbkbm_kbtrans, key, state);
1454 }
1455 
1456 /*
1457  * Translate USB scancodes to PC scancodes before sending it to 'kbtrans'
1458  */
1459 void
1460 usbkbm_usb2pc_xlate(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1461 {
1462 	key = kbtrans_keycode_usb2pc(key);
1463 	kbtrans_streams_key(usbkbmd->usbkbm_kbtrans, key, state);
1464 }
1465 
1466 /*
1467  * usbkbm_poll_callback :
1468  *	This is the routine that is going to be called when unpacking
1469  *	usb packets for polled input.  We pass a pointer to this routine
1470  *	to usbkbm_unpack_usb_packet.  This routine will get called with
1471  *	an unpacked key (scancode) and state (press/release).  We will
1472  *	store the key/state pair into a circular buffer so that it can
1473  *	be translated into an ascii key later.
1474  */
1475 static void
1476 usbkbm_poll_callback(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1477 {
1478 	/*
1479 	 * Check to make sure that the buffer isn't already full
1480 	 */
1481 	if (usbkbmd->usbkbm_polled_buffer_num_characters ==
1482 	    USB_POLLED_BUFFER_SIZE) {
1483 
1484 		/*
1485 		 * The buffer is full, we will drop this character.
1486 		 */
1487 		return;
1488 	}
1489 
1490 	/*
1491 	 * Save the scancode in the buffer
1492 	 */
1493 	usbkbmd->usbkbm_polled_buffer_head->poll_key = key;
1494 	usbkbmd->usbkbm_polled_buffer_head->poll_state = state;
1495 
1496 	/*
1497 	 * We have one more character in the buffer
1498 	 */
1499 	usbkbmd->usbkbm_polled_buffer_num_characters++;
1500 
1501 	/*
1502 	 * Increment to the next available slot.
1503 	 */
1504 	usbkbmd->usbkbm_polled_buffer_head++;
1505 
1506 	/*
1507 	 * Check to see if the tail has wrapped.
1508 	 */
1509 	if (usbkbmd->usbkbm_polled_buffer_head -
1510 	    usbkbmd->usbkbm_polled_scancode_buffer ==
1511 	    USB_POLLED_BUFFER_SIZE) {
1512 
1513 		usbkbmd->usbkbm_polled_buffer_head =
1514 		    usbkbmd->usbkbm_polled_scancode_buffer;
1515 	}
1516 }
1517 
1518 /*
1519  * usbkbm_get_scancode :
1520  *	This routine retreives a key/state pair from the circular buffer.
1521  *	The pair was put in the buffer by usbkbm_poll_callback when a
1522  *	USB packet was translated into a key/state by usbkbm_unpack_usb_packet.
1523  */
1524 static void
1525 usbkbm_get_scancode(usbkbm_state_t *usbkbmd, int *key, enum keystate *state)
1526 {
1527 	/*
1528 	 * Copy the character.
1529 	 */
1530 	*key = usbkbmd->usbkbm_polled_buffer_tail->poll_key;
1531 	*state = usbkbmd->usbkbm_polled_buffer_tail->poll_state;
1532 
1533 	/*
1534 	 * Increment to the next character to be copied from
1535 	 * and to.
1536 	 */
1537 	usbkbmd->usbkbm_polled_buffer_tail++;
1538 
1539 	/*
1540 	 * Check to see if the tail has wrapped.
1541 	 */
1542 	if (usbkbmd->usbkbm_polled_buffer_tail -
1543 	    usbkbmd->usbkbm_polled_scancode_buffer ==
1544 	    USB_POLLED_BUFFER_SIZE) {
1545 
1546 		usbkbmd->usbkbm_polled_buffer_tail =
1547 		    usbkbmd->usbkbm_polled_scancode_buffer;
1548 	}
1549 
1550 	/*
1551 	 * We have one less character in the buffer.
1552 	 */
1553 	usbkbmd->usbkbm_polled_buffer_num_characters--;
1554 }
1555 
1556 /*
1557  * usbkbm_polled_setled :
1558  *	This routine is a place holder.  Someday, we may want to allow led
1559  *	state to be updated from within polled mode.
1560  */
1561 /* ARGSUSED */
1562 static void
1563 usbkbm_polled_setled(struct kbtrans_hardware *hw, int led_state)
1564 {
1565 	/* nothing to do for now */
1566 }
1567 
1568 /*
1569  * This is a pass-thru routine to get a character at poll time.
1570  */
1571 static int
1572 usbkbm_polled_getchar(cons_polledio_arg_t arg)
1573 {
1574 	usbkbm_state_t			*usbkbmd;
1575 
1576 	usbkbmd = (usbkbm_state_t *)arg;
1577 
1578 	return (kbtrans_getchar(usbkbmd->usbkbm_kbtrans));
1579 }
1580 
1581 /*
1582  * This is a pass-thru routine to test if character is available for reading
1583  * at poll time.
1584  */
1585 static boolean_t
1586 usbkbm_polled_ischar(cons_polledio_arg_t arg)
1587 {
1588 	usbkbm_state_t			*usbkbmd;
1589 
1590 	usbkbmd = (usbkbm_state_t *)arg;
1591 
1592 	return (kbtrans_ischar(usbkbmd->usbkbm_kbtrans));
1593 }
1594 
1595 /*
1596  * usbkbm_polled_input_enter :
1597  *	This is a pass-thru initialization routine for the lower layer drivers.
1598  *	This routine is called at poll time to set the state for polled input.
1599  */
1600 static void
1601 usbkbm_polled_enter(cons_polledio_arg_t arg)
1602 {
1603 	usbkbm_state_t		*usbkbmd = (usbkbm_state_t *)arg;
1604 	hid_polled_handle_t	hid_polled_handle;
1605 	int			kbstart, kbend, uindex;
1606 
1607 	kbstart = usbkbmd->usbkbm_report_format.kpos;
1608 	kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1609 
1610 	/*
1611 	 * Before switching to POLLED mode, copy the contents of
1612 	 * usbkbm_pendingusbpacket to usbkbm_lastusbpacket since
1613 	 * usbkbm_pendingusbpacket field has currently processed
1614 	 * key events of the current OS mode usb keyboard packet.
1615 	 */
1616 	for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1617 		usbkbmd->usbkbm_lastusbpacket[uindex] =
1618 		    usbkbmd->usbkbm_pendingusbpacket[uindex];
1619 
1620 		usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1621 	}
1622 
1623 	hid_polled_handle =
1624 	    usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1625 
1626 	(void) (usbkbmd->usbkbm_hid_callback.hid_polled_input_enter)
1627 	    (hid_polled_handle);
1628 }
1629 
1630 /*
1631  * usbkbm_polled_input_exit :
1632  *	This is a pass-thru restoration routine for the lower layer drivers.
1633  *	This routine is called at poll time to reset the state back to streams
1634  *	input.
1635  */
1636 static void
1637 usbkbm_polled_exit(cons_polledio_arg_t arg)
1638 {
1639 	usbkbm_state_t		*usbkbmd = (usbkbm_state_t *)arg;
1640 	hid_polled_handle_t	hid_polled_handle;
1641 	int			kbstart, kbend, uindex;
1642 
1643 	kbstart = usbkbmd->usbkbm_report_format.kpos;
1644 	kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1645 
1646 	/*
1647 	 * Before returning to OS mode, copy the contents of
1648 	 * usbkbm_lastusbpacket to usbkbm_pendingusbpacket since
1649 	 * usbkbm_lastusbpacket field has processed key events
1650 	 * of the last POLLED mode usb keyboard packet.
1651 	 */
1652 	for (uindex = kbstart + 2; uindex < kbend; uindex ++) {
1653 		usbkbmd->usbkbm_pendingusbpacket[uindex] =
1654 		    usbkbmd->usbkbm_lastusbpacket[uindex];
1655 
1656 		usbkbmd->usbkbm_lastusbpacket[uindex] = 0;
1657 	}
1658 
1659 	hid_polled_handle =
1660 	    usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1661 
1662 	(void) (usbkbmd->usbkbm_hid_callback.hid_polled_input_exit)
1663 	    (hid_polled_handle);
1664 }
1665 
1666 /*
1667  * usbkbm_unpack_usb_packet :
1668  *	USB key packets contain 8 bytes while in boot-protocol mode.
1669  *	The first byte contains bit packed modifier key information.
1670  *	Second byte is reserved. The last 6 bytes contain bytes of
1671  *	currently pressed keys. If a key was not recorded on the
1672  *	previous packet, but present in the current packet, then set
1673  *	state to KEY_PRESSED. If a key was recorded in the previous packet,
1674  *	but not present in the current packet, then state to KEY_RELEASED
1675  *	Follow a similar algorithm for bit packed modifier keys.
1676  */
1677 static void
1678 usbkbm_unpack_usb_packet(usbkbm_state_t *usbkbmd, process_key_callback_t func,
1679     uchar_t *usbpacket)
1680 {
1681 	uchar_t		mkb;
1682 	uchar_t		lastmkb;
1683 	uchar_t		*lastusbpacket = usbkbmd->usbkbm_lastusbpacket;
1684 	int		packet_size, kbstart, kbend;
1685 	int		uindex, lindex, rollover;
1686 
1687 	packet_size = usbkbmd->usbkbm_report_format.tlen;
1688 	kbstart = usbkbmd->usbkbm_report_format.kpos;
1689 	kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1690 	mkb = usbpacket[kbstart];
1691 	lastmkb = lastusbpacket[kbstart];
1692 
1693 	for (uindex = 0; uindex < packet_size; uindex++) {
1694 
1695 		USB_DPRINTF_L3(PRINT_MASK_PACKET, usbkbm_log_handle,
1696 		    " %x ", usbpacket[uindex]);
1697 	}
1698 
1699 	USB_DPRINTF_L3(PRINT_MASK_PACKET, usbkbm_log_handle,
1700 	    " is the usbkeypacket");
1701 
1702 	/* check to see if modifier keys are different */
1703 	if (mkb != lastmkb) {
1704 
1705 		if ((mkb & USB_LSHIFTBIT) != (lastmkb & USB_LSHIFTBIT)) {
1706 			(*func)(usbkbmd, USB_LSHIFTKEY, (mkb&USB_LSHIFTBIT) ?
1707 			    KEY_PRESSED : KEY_RELEASED);
1708 			USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1709 			    "unpack: sending USB_LSHIFTKEY");
1710 		}
1711 
1712 		if ((mkb & USB_LCTLBIT) != (lastmkb & USB_LCTLBIT)) {
1713 			(*func)(usbkbmd, USB_LCTLCKEY, mkb&USB_LCTLBIT ?
1714 			    KEY_PRESSED : KEY_RELEASED);
1715 		}
1716 
1717 		if ((mkb & USB_LALTBIT) != (lastmkb & USB_LALTBIT)) {
1718 			(*func)(usbkbmd, USB_LALTKEY, mkb&USB_LALTBIT ?
1719 			    KEY_PRESSED : KEY_RELEASED);
1720 		}
1721 
1722 		if ((mkb & USB_LMETABIT) != (lastmkb & USB_LMETABIT)) {
1723 			(*func)(usbkbmd, USB_LMETAKEY, mkb&USB_LMETABIT ?
1724 			    KEY_PRESSED : KEY_RELEASED);
1725 		}
1726 
1727 		if ((mkb & USB_RMETABIT) != (lastmkb & USB_RMETABIT)) {
1728 			(*func)(usbkbmd, USB_RMETAKEY, mkb&USB_RMETABIT ?
1729 			    KEY_PRESSED : KEY_RELEASED);
1730 		}
1731 
1732 		if ((mkb & USB_RALTBIT) != (lastmkb & USB_RALTBIT)) {
1733 			(*func)(usbkbmd, USB_RALTKEY, mkb&USB_RALTBIT ?
1734 			    KEY_PRESSED : KEY_RELEASED);
1735 		}
1736 
1737 		if ((mkb & USB_RCTLBIT) != (lastmkb & USB_RCTLBIT)) {
1738 			(*func)(usbkbmd, USB_RCTLCKEY, mkb&USB_RCTLBIT ?
1739 			    KEY_PRESSED : KEY_RELEASED);
1740 		}
1741 
1742 		if ((mkb & USB_RSHIFTBIT) != (lastmkb & USB_RSHIFTBIT)) {
1743 			(*func)(usbkbmd, USB_RSHIFTKEY, mkb&USB_RSHIFTBIT ?
1744 			    KEY_PRESSED : KEY_RELEASED);
1745 			USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1746 			    "unpack: sending USB_RSHIFTKEY");
1747 		}
1748 	}
1749 
1750 	/* save modifier bits */
1751 	lastusbpacket[kbstart] = usbpacket[kbstart];
1752 
1753 	/* Check Keyboard rollover error. */
1754 	if (usbpacket[kbstart + 2] == USB_ERRORROLLOVER) {
1755 		rollover = 1;
1756 		for (uindex = kbstart + 3; uindex < kbend;
1757 		    uindex++) {
1758 			if (usbpacket[uindex] != USB_ERRORROLLOVER) {
1759 				rollover = 0;
1760 				break;
1761 			}
1762 		}
1763 		if (rollover) {
1764 			USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1765 			    "unpack: errorrollover");
1766 			return;
1767 		}
1768 	}
1769 
1770 	/* check for released keys */
1771 	for (lindex = kbstart + 2; lindex < kbend; lindex++) {
1772 		int released = 1;
1773 
1774 		if (lastusbpacket[lindex] == 0) {
1775 			continue;
1776 		}
1777 		for (uindex = kbstart + 2; uindex < kbend; uindex++)
1778 			if (usbpacket[uindex] == lastusbpacket[lindex]) {
1779 				released = 0;
1780 				break;
1781 			}
1782 		if (released) {
1783 			(*func)(usbkbmd, lastusbpacket[lindex], KEY_RELEASED);
1784 		}
1785 	}
1786 
1787 	/* check for new presses */
1788 	for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1789 		int newkey = 1;
1790 
1791 		usbkbmd->usbkbm_pendingusbpacket[uindex] = usbpacket[uindex];
1792 
1793 		if (usbpacket[uindex] == 0) {
1794 			continue;
1795 		}
1796 
1797 		for (lindex = kbstart + 2; lindex < kbend; lindex++) {
1798 			if (usbpacket[uindex] == lastusbpacket[lindex]) {
1799 				newkey = 0;
1800 				break;
1801 			}
1802 		}
1803 
1804 		if (newkey) {
1805 			/*
1806 			 * Modifier keys can be present as part of both the
1807 			 * first byte and as separate key bytes. In the sec-
1808 			 * ond case ignore it.
1809 			 */
1810 
1811 			if (!usbkbm_is_modkey(usbpacket[uindex])) {
1812 				(*func)(usbkbmd, usbpacket[uindex],
1813 				    KEY_PRESSED);
1814 			} else {
1815 				usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1816 
1817 				continue;
1818 			}
1819 		}
1820 	}
1821 
1822 	/*
1823 	 * Copy the processed key events of the current usb keyboard
1824 	 * packet, which is saved in the usbkbm_pendingusbpacket field
1825 	 * to the usbkbm_lastusbpacket field.
1826 	 */
1827 	for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1828 		lastusbpacket[uindex] =
1829 		    usbkbmd->usbkbm_pendingusbpacket[uindex];
1830 		usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1831 	}
1832 }
1833 
1834 static boolean_t
1835 usbkbm_is_modkey(uchar_t key)
1836 {
1837 
1838 	switch (key) {
1839 
1840 	case USB_LSHIFTKEY:
1841 	case USB_LCTLCKEY:
1842 	case USB_LALTKEY:
1843 	case USB_LMETAKEY:
1844 	case USB_RCTLCKEY:
1845 	case USB_RSHIFTKEY:
1846 	case USB_RMETAKEY:
1847 	case USB_RALTKEY:
1848 
1849 		return (B_TRUE);
1850 
1851 	default:
1852 
1853 		break;
1854 	}
1855 
1856 	return (B_FALSE);
1857 }
1858 
1859 /*
1860  * usbkbm_reioctl :
1861  *	This function is set up as call-back function should an ioctl fail.
1862  *	It retries the ioctl
1863  */
1864 static void
1865 usbkbm_reioctl(void	*arg)
1866 {
1867 	usbkbm_state_t	*usbkbmd;
1868 	mblk_t *mp;
1869 
1870 	usbkbmd = (usbkbm_state_t *)arg;
1871 
1872 	usbkbmd->usbkbm_streams_bufcallid = 0;
1873 
1874 	if ((mp = usbkbmd->usbkbm_streams_iocpending) != NULL) {
1875 
1876 		/* not pending any more */
1877 		usbkbmd->usbkbm_streams_iocpending = NULL;
1878 
1879 		(void) usbkbm_ioctl(usbkbmd->usbkbm_writeq, mp);
1880 	}
1881 }
1882 
1883 /*
1884  * usbkbm_get_vid_pid
1885  *	Issue a M_CTL to hid to get the device info
1886  */
1887 static int
1888 usbkbm_get_vid_pid(usbkbm_state_t *usbkbmd)
1889 {
1890 	struct iocblk mctlmsg;
1891 	mblk_t *mctl_ptr;
1892 	queue_t *q = usbkbmd->usbkbm_readq;
1893 
1894 	mctlmsg.ioc_cmd = HID_GET_VID_PID;
1895 	mctlmsg.ioc_count = 0;
1896 
1897 	mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
1898 	if (mctl_ptr == NULL) {
1899 		(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
1900 		qprocsoff(q);
1901 		kmem_free(usbkbmd, sizeof (usbkbm_state_t));
1902 
1903 		return (ENOMEM);
1904 	}
1905 
1906 	putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
1907 	usbkbmd->usbkbm_flags |= USBKBM_QWAIT;
1908 	while (usbkbmd->usbkbm_flags & USBKBM_QWAIT) {
1909 		if (qwait_sig(q) == 0) {
1910 			usbkbmd->usbkbm_flags = 0;
1911 			(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
1912 			qprocsoff(q);
1913 			kmem_free(usbkbmd, sizeof (usbkbm_state_t));
1914 
1915 			return (EINTR);
1916 		}
1917 	}
1918 
1919 	return (0);
1920 }
1921 
1922 /*
1923  * usbkbm_get_input_format() :
1924  *     Get the input report format of keyboard
1925  */
1926 static int
1927 usbkbm_get_input_format(usbkbm_state_t *usbkbmd)
1928 {
1929 
1930 	hidparser_rpt_t *kb_rpt;
1931 	uint_t i, kbd_page = 0, kpos = 0, klen = 0, limit = 0;
1932 	uint32_t rptcnt, rptsz;
1933 	usbkbm_report_format_t *kbd_fmt = &usbkbmd->usbkbm_report_format;
1934 	int rptid, rval;
1935 
1936 	/* Setup default input report format */
1937 	kbd_fmt->keyid = HID_REPORT_ID_UNDEFINED;
1938 	kbd_fmt->tlen = USB_KBD_BOOT_PROTOCOL_PACKET_SIZE;
1939 	kbd_fmt->klen = kbd_fmt->tlen;
1940 	kbd_fmt->kpos = 0;
1941 
1942 	if (usbkbmd->usbkbm_report_descr == NULL) {
1943 		return (USB_FAILURE);
1944 	}
1945 
1946 	/* Get keyboard layout */
1947 	if (hidparser_get_country_code(usbkbmd->usbkbm_report_descr,
1948 	    (uint16_t *)&usbkbmd->usbkbm_layout) == HIDPARSER_FAILURE) {
1949 
1950 		USB_DPRINTF_L3(PRINT_MASK_OPEN,
1951 		    usbkbm_log_handle, "get_country_code failed"
1952 		    "setting default layout(0)");
1953 
1954 		usbkbmd->usbkbm_layout = usbkbm_layout;
1955 	}
1956 
1957 	/* Get the id of the report which contains keyboard data */
1958 	if (hidparser_get_usage_attribute(
1959 	    usbkbmd->usbkbm_report_descr,
1960 	    0, /* Doesn't matter */
1961 	    HIDPARSER_ITEM_INPUT,
1962 	    HID_KEYBOARD_KEYPAD_KEYS,
1963 	    0,
1964 	    HIDPARSER_ITEM_REPORT_ID,
1965 	    &rptid) == HIDPARSER_NOT_FOUND) {
1966 
1967 		return (USB_SUCCESS);
1968 	}
1969 
1970 	/* Allocate hidparser report structure */
1971 	kb_rpt = kmem_zalloc(sizeof (hidparser_rpt_t), KM_SLEEP);
1972 
1973 	/*
1974 	 * Check what is the total length of the keyboard packet
1975 	 * and get the usages and their lengths in order
1976 	 */
1977 	rval = hidparser_get_usage_list_in_order(
1978 	    usbkbmd->usbkbm_report_descr,
1979 	    rptid,
1980 	    HIDPARSER_ITEM_INPUT,
1981 	    kb_rpt);
1982 	if (rval != HIDPARSER_SUCCESS) {
1983 
1984 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
1985 		    "get_usage_list_in_order failed");
1986 		kmem_free(kb_rpt, sizeof (hidparser_rpt_t));
1987 		return (USB_FAILURE);
1988 	}
1989 
1990 	for (i = 0; i < kb_rpt->no_of_usages; i++) {
1991 		rptcnt = kb_rpt->usage_descr[i].rptcnt;
1992 		rptsz = kb_rpt->usage_descr[i].rptsz;
1993 
1994 		switch (kb_rpt->usage_descr[i].usage_page) {
1995 		case HID_KEYBOARD_KEYPAD_KEYS:
1996 			if (!kbd_page) {
1997 				kpos = limit;
1998 				kbd_page = 1;
1999 			}
2000 			klen += rptcnt * rptsz;
2001 			/*FALLTHRU*/
2002 		default:
2003 			limit += rptcnt * rptsz;
2004 			break;
2005 		}
2006 	}
2007 
2008 	kmem_free(kb_rpt, sizeof (hidparser_rpt_t));
2009 
2010 	/* Invalid input report format */
2011 	if (!kbd_page || limit > USBKBM_MAXPKTSIZE * 8 ||
2012 	    kpos + klen > limit || (kpos % 8 != 0)) {
2013 
2014 		USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
2015 		    "Invalid input report format: kbd_page (%d), limit (%d), "
2016 		    "kpos (%d), klen (%d)", kbd_page, limit, kpos, klen);
2017 		return (USB_FAILURE);
2018 	}
2019 
2020 	/* Set report format */
2021 	kbd_fmt->keyid = (uint8_t)rptid;
2022 	kbd_fmt->tlen = limit / 8 + 1;
2023 	kbd_fmt->klen = klen / 8;
2024 	kbd_fmt->kpos = kpos / 8;
2025 
2026 	return (USB_SUCCESS);
2027 }
2028