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