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