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