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