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