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