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