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