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