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