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