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