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