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