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