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 /* 23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2016 Joyent, Inc. 25 */ 26 27 28 /* 29 * Human Interface Device driver (HID) 30 * 31 * The HID driver is a software driver which acts as a class 32 * driver for USB human input devices like keyboard, mouse, 33 * joystick etc and provides the class-specific interfaces 34 * between these client driver modules and the Universal Serial 35 * Bus Driver(USBA). 36 * 37 * NOTE: This driver is not DDI compliant in that it uses undocumented 38 * functions for logging (USB_DPRINTF_L*, usb_alloc_log_hdl, usb_free_log_hdl). 39 * 40 * Undocumented functions may go away in a future Solaris OS release. 41 * 42 * Please see the DDK for sample code of these functions, and for the usbskel 43 * skeleton template driver which contains scaled-down versions of these 44 * functions written in a DDI-compliant way. 45 */ 46 47 #define USBDRV_MAJOR_VER 2 48 #define USBDRV_MINOR_VER 0 49 50 #include <sys/usb/usba.h> 51 #include <sys/usb/usba/genconsole.h> 52 #include <sys/usb/clients/hid/hid.h> 53 #include <sys/usb/clients/hid/hid_polled.h> 54 #include <sys/usb/clients/hidparser/hidparser.h> 55 #include <sys/usb/clients/hid/hidvar.h> 56 #include <sys/usb/clients/hid/hidminor.h> 57 #include <sys/usb/clients/hidparser/hid_parser_driver.h> 58 #include <sys/stropts.h> 59 #include <sys/sunddi.h> 60 #include <sys/stream.h> 61 #include <sys/strsun.h> 62 63 extern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t); 64 65 /* Debugging support */ 66 uint_t hid_errmask = (uint_t)PRINT_MASK_ALL; 67 uint_t hid_errlevel = USB_LOG_L4; 68 uint_t hid_instance_debug = (uint_t)-1; 69 70 /* tunables */ 71 int hid_default_pipe_drain_timeout = HID_DEFAULT_PIPE_DRAIN_TIMEOUT; 72 int hid_pm_mouse = 1; /* enable remote_wakeup for USB mouse/keyboard */ 73 74 /* soft state structures */ 75 #define HID_INITIAL_SOFT_SPACE 4 76 static void *hid_statep; 77 78 /* Callbacks */ 79 static void hid_interrupt_pipe_callback(usb_pipe_handle_t, 80 usb_intr_req_t *); 81 static void hid_default_pipe_callback(usb_pipe_handle_t, usb_ctrl_req_t *); 82 static void hid_interrupt_pipe_exception_callback(usb_pipe_handle_t, 83 usb_intr_req_t *); 84 static void hid_default_pipe_exception_callback(usb_pipe_handle_t, 85 usb_ctrl_req_t *); 86 static int hid_restore_state_event_callback(dev_info_t *); 87 static int hid_disconnect_event_callback(dev_info_t *); 88 static int hid_cpr_suspend(hid_state_t *hidp); 89 static void hid_cpr_resume(hid_state_t *hidp); 90 static void hid_power_change_callback(void *arg, int rval); 91 92 /* Supporting routines */ 93 static size_t hid_parse_hid_descr(usb_hid_descr_t *, size_t, 94 usb_alt_if_data_t *, usb_ep_data_t *); 95 static int hid_parse_hid_descr_failure(hid_state_t *); 96 static int hid_handle_report_descriptor(hid_state_t *, int); 97 static void hid_set_idle(hid_state_t *); 98 static void hid_set_protocol(hid_state_t *, int); 99 static void hid_detach_cleanup(dev_info_t *, hid_state_t *); 100 101 static int hid_start_intr_polling(hid_state_t *); 102 static void hid_close_intr_pipe(hid_state_t *); 103 static int hid_mctl_execute_cmd(queue_t *, int, hid_req_t *, 104 mblk_t *); 105 static int hid_mctl_receive(queue_t *, mblk_t *); 106 static int hid_send_async_ctrl_request(hid_default_pipe_arg_t *, hid_req_t *, 107 uchar_t, int, ushort_t); 108 109 static void hid_create_pm_components(dev_info_t *, hid_state_t *); 110 static int hid_is_pm_enabled(dev_info_t *); 111 static void hid_restore_device_state(dev_info_t *, hid_state_t *); 112 static void hid_save_device_state(hid_state_t *); 113 114 static void hid_qreply_merror(queue_t *, mblk_t *, uchar_t); 115 static mblk_t *hid_data2mblk(uchar_t *, int); 116 static void hid_flush(queue_t *); 117 118 static int hid_pwrlvl0(hid_state_t *); 119 static int hid_pwrlvl1(hid_state_t *); 120 static int hid_pwrlvl2(hid_state_t *); 121 static int hid_pwrlvl3(hid_state_t *); 122 static void hid_pm_busy_component(hid_state_t *); 123 static void hid_pm_idle_component(hid_state_t *); 124 125 static int hid_polled_read(hid_polled_handle_t, uchar_t **); 126 static int hid_polled_input_enter(hid_polled_handle_t); 127 static int hid_polled_input_exit(hid_polled_handle_t); 128 static int hid_polled_input_init(hid_state_t *); 129 static int hid_polled_input_fini(hid_state_t *); 130 131 /* Streams entry points */ 132 static int hid_open(queue_t *, dev_t *, int, int, cred_t *); 133 static int hid_close(queue_t *, int, cred_t *); 134 static int hid_wput(queue_t *, mblk_t *); 135 static int hid_wsrv(queue_t *); 136 137 /* dev_ops entry points */ 138 static int hid_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 139 static int hid_attach(dev_info_t *, ddi_attach_cmd_t); 140 static int hid_detach(dev_info_t *, ddi_detach_cmd_t); 141 static int hid_power(dev_info_t *, int, int); 142 143 /* 144 * Warlock is not aware of the automatic locking mechanisms for 145 * streams drivers. The hid streams enter points are protected by 146 * a per module perimeter. If the locking in hid is a bottleneck 147 * per queue pair or per queue locking may be used. Since warlock 148 * is not aware of the streams perimeters, these notes have been added. 149 * 150 * Note that the perimeters do not protect the driver from callbacks 151 * happening while a streams entry point is executing. So, the hid_mutex 152 * has been created to protect the data. 153 */ 154 _NOTE(SCHEME_PROTECTS_DATA("unique per call", iocblk)) 155 _NOTE(SCHEME_PROTECTS_DATA("unique per call", datab)) 156 _NOTE(SCHEME_PROTECTS_DATA("unique per call", msgb)) 157 _NOTE(SCHEME_PROTECTS_DATA("unique per call", queue)) 158 _NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_ctrl_req)) 159 _NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_intr_req)) 160 161 /* module information */ 162 static struct module_info hid_mod_info = { 163 0x0ffff, /* module id number */ 164 "hid", /* module name */ 165 0, /* min packet size accepted */ 166 INFPSZ, /* max packet size accepted */ 167 512, /* hi-water mark */ 168 128 /* lo-water mark */ 169 }; 170 171 /* read queue information structure */ 172 static struct qinit rinit = { 173 NULL, /* put procedure not needed */ 174 NULL, /* service procedure not needed */ 175 hid_open, /* called on startup */ 176 hid_close, /* called on finish */ 177 NULL, /* for future use */ 178 &hid_mod_info, /* module information structure */ 179 NULL /* module statistics structure */ 180 }; 181 182 /* write queue information structure */ 183 static struct qinit winit = { 184 hid_wput, /* put procedure */ 185 hid_wsrv, /* service procedure */ 186 NULL, /* open not used on write side */ 187 NULL, /* close not used on write side */ 188 NULL, /* for future use */ 189 &hid_mod_info, /* module information structure */ 190 NULL /* module statistics structure */ 191 }; 192 193 struct streamtab hid_streamtab = { 194 &rinit, 195 &winit, 196 NULL, /* not a MUX */ 197 NULL /* not a MUX */ 198 }; 199 200 struct cb_ops hid_cb_ops = { 201 nulldev, /* open */ 202 nulldev, /* close */ 203 nulldev, /* strategy */ 204 nulldev, /* print */ 205 nulldev, /* dump */ 206 nulldev, /* read */ 207 nulldev, /* write */ 208 nulldev, /* ioctl */ 209 nulldev, /* devmap */ 210 nulldev, /* mmap */ 211 nulldev, /* segmap */ 212 nochpoll, /* poll */ 213 ddi_prop_op, /* cb_prop_op */ 214 &hid_streamtab, /* streamtab */ 215 D_MP | D_MTPERQ 216 }; 217 218 219 static struct dev_ops hid_ops = { 220 DEVO_REV, /* devo_rev, */ 221 0, /* refcnt */ 222 hid_info, /* info */ 223 nulldev, /* identify */ 224 nulldev, /* probe */ 225 hid_attach, /* attach */ 226 hid_detach, /* detach */ 227 nodev, /* reset */ 228 &hid_cb_ops, /* driver operations */ 229 NULL, /* bus operations */ 230 hid_power, /* power */ 231 ddi_quiesce_not_needed, /* quiesce */ 232 }; 233 234 static struct modldrv hidmodldrv = { 235 &mod_driverops, 236 "USB HID Client Driver", 237 &hid_ops /* driver ops */ 238 }; 239 240 static struct modlinkage modlinkage = { 241 MODREV_1, 242 &hidmodldrv, 243 NULL, 244 }; 245 246 static usb_event_t hid_events = { 247 hid_disconnect_event_callback, 248 hid_restore_state_event_callback, 249 NULL, 250 NULL, 251 }; 252 253 254 int 255 _init(void) 256 { 257 int rval; 258 259 if (((rval = ddi_soft_state_init(&hid_statep, sizeof (hid_state_t), 260 HID_INITIAL_SOFT_SPACE)) != 0)) { 261 262 return (rval); 263 } 264 265 if ((rval = mod_install(&modlinkage)) != 0) { 266 ddi_soft_state_fini(&hid_statep); 267 } 268 269 return (rval); 270 } 271 272 273 int 274 _fini(void) 275 { 276 int rval; 277 278 if ((rval = mod_remove(&modlinkage)) != 0) { 279 280 return (rval); 281 } 282 283 ddi_soft_state_fini(&hid_statep); 284 285 return (rval); 286 } 287 288 289 int 290 _info(struct modinfo *modinfop) 291 { 292 return (mod_info(&modlinkage, modinfop)); 293 } 294 295 296 /* 297 * hid_info : 298 * Get minor number, soft state structure etc. 299 */ 300 /*ARGSUSED*/ 301 static int 302 hid_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 303 { 304 hid_state_t *hidp = NULL; 305 int error = DDI_FAILURE; 306 minor_t minor = getminor((dev_t)arg); 307 int instance = HID_MINOR_TO_INSTANCE(minor); 308 309 switch (infocmd) { 310 case DDI_INFO_DEVT2DEVINFO: 311 if ((hidp = ddi_get_soft_state(hid_statep, instance)) != NULL) { 312 *result = hidp->hid_dip; 313 if (*result != NULL) { 314 error = DDI_SUCCESS; 315 } 316 } else 317 *result = NULL; 318 break; 319 case DDI_INFO_DEVT2INSTANCE: 320 *result = (void *)(uintptr_t)instance; 321 error = DDI_SUCCESS; 322 break; 323 default: 324 break; 325 } 326 327 return (error); 328 } 329 330 331 /* 332 * hid_attach : 333 * Gets called at the time of attach. Do allocation, 334 * and initialization of the software structure. 335 * Get all the descriptors, setup the 336 * report descriptor tree by calling hidparser 337 * function. 338 */ 339 static int 340 hid_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 341 { 342 343 int instance = ddi_get_instance(dip); 344 int parse_hid_descr_error = 0; 345 hid_state_t *hidp = NULL; 346 uint32_t usage_page; 347 uint32_t usage; 348 usb_client_dev_data_t *dev_data; 349 usb_alt_if_data_t *altif_data; 350 char minor_name[HID_MINOR_NAME_LEN]; 351 usb_ep_data_t *ep_data; 352 353 switch (cmd) { 354 case DDI_ATTACH: 355 break; 356 case DDI_RESUME: 357 hidp = ddi_get_soft_state(hid_statep, instance); 358 hid_cpr_resume(hidp); 359 return (DDI_SUCCESS); 360 default: 361 362 return (DDI_FAILURE); 363 } 364 365 /* 366 * Allocate softstate information and get softstate pointer 367 */ 368 if (ddi_soft_state_zalloc(hid_statep, instance) == DDI_SUCCESS) { 369 hidp = ddi_get_soft_state(hid_statep, instance); 370 } 371 if (hidp == NULL) { 372 373 goto fail; 374 } 375 376 hidp->hid_log_handle = usb_alloc_log_hdl(dip, NULL, &hid_errlevel, 377 &hid_errmask, &hid_instance_debug, 0); 378 379 hidp->hid_instance = instance; 380 hidp->hid_dip = dip; 381 382 /* 383 * Register with USBA. Just retrieve interface descriptor 384 */ 385 if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) { 386 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 387 "hid_attach: client attach failed"); 388 389 goto fail; 390 } 391 392 if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) != 393 USB_SUCCESS) { 394 395 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 396 "hid_attach: usb_get_dev_data() failed"); 397 398 goto fail; 399 } 400 401 /* initialize mutex */ 402 mutex_init(&hidp->hid_mutex, NULL, MUTEX_DRIVER, 403 dev_data->dev_iblock_cookie); 404 405 hidp->hid_attach_flags |= HID_LOCK_INIT; 406 407 /* get interface data for alternate 0 */ 408 altif_data = &dev_data->dev_curr_cfg-> 409 cfg_if[dev_data->dev_curr_if].if_alt[0]; 410 411 mutex_enter(&hidp->hid_mutex); 412 hidp->hid_dev_data = dev_data; 413 hidp->hid_dev_descr = dev_data->dev_descr; 414 hidp->hid_interfaceno = dev_data->dev_curr_if; 415 hidp->hid_if_descr = altif_data->altif_descr; 416 /* 417 * Make sure that the bInterfaceProtocol only has meaning to 418 * Boot Interface Subclass. 419 */ 420 if (hidp->hid_if_descr.bInterfaceSubClass != BOOT_INTERFACE) 421 hidp->hid_if_descr.bInterfaceProtocol = NONE_PROTOCOL; 422 mutex_exit(&hidp->hid_mutex); 423 424 if ((ep_data = usb_lookup_ep_data(dip, dev_data, 425 hidp->hid_interfaceno, 0, 0, 426 (uint_t)USB_EP_ATTR_INTR, (uint_t)USB_EP_DIR_IN)) == NULL) { 427 428 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 429 "no interrupt IN endpoint found"); 430 431 goto fail; 432 } 433 434 mutex_enter(&hidp->hid_mutex); 435 if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION, dip, ep_data, 436 &hidp->hid_ep_intr_xdescr) != USB_SUCCESS) { 437 mutex_exit(&hidp->hid_mutex); 438 439 goto fail; 440 } 441 442 /* 443 * Attempt to find the hid descriptor, it could be after interface 444 * or after endpoint descriptors 445 */ 446 if (hid_parse_hid_descr(&hidp->hid_hid_descr, USB_HID_DESCR_SIZE, 447 altif_data, ep_data) != USB_HID_DESCR_SIZE) { 448 /* 449 * If parsing of hid descriptor failed and 450 * the device is a keyboard or mouse, use predefined 451 * length and packet size. 452 */ 453 if (hid_parse_hid_descr_failure(hidp) == USB_FAILURE) { 454 mutex_exit(&hidp->hid_mutex); 455 456 goto fail; 457 } 458 459 /* 460 * hid descriptor was bad but since 461 * the device is a keyboard or mouse, 462 * we will use the default length 463 * and packet size. 464 */ 465 parse_hid_descr_error = HID_BAD_DESCR; 466 } else { 467 /* Parse hid descriptor successful */ 468 469 USB_DPRINTF_L3(PRINT_MASK_ATTA, hidp->hid_log_handle, 470 "Hid descriptor:\n\t" 471 "bLength = 0x%x bDescriptorType = 0x%x " 472 "bcdHID = 0x%x\n\t" 473 "bCountryCode = 0x%x bNumDescriptors = 0x%x\n\t" 474 "bReportDescriptorType = 0x%x\n\t" 475 "wReportDescriptorLength = 0x%x", 476 hidp->hid_hid_descr.bLength, 477 hidp->hid_hid_descr.bDescriptorType, 478 hidp->hid_hid_descr.bcdHID, 479 hidp->hid_hid_descr.bCountryCode, 480 hidp->hid_hid_descr.bNumDescriptors, 481 hidp->hid_hid_descr.bReportDescriptorType, 482 hidp->hid_hid_descr.wReportDescriptorLength); 483 } 484 485 /* 486 * Save a copy of the default pipe for easy reference 487 */ 488 hidp->hid_default_pipe = hidp->hid_dev_data->dev_default_ph; 489 490 /* we copied the descriptors we need, free the dev_data */ 491 usb_free_dev_data(dip, dev_data); 492 hidp->hid_dev_data = NULL; 493 494 /* 495 * Don't get the report descriptor if parsing hid descriptor earlier 496 * failed since device probably won't return valid report descriptor 497 * either. Though parsing of hid descriptor failed, we have reached 498 * this point because the device has been identified as a 499 * keyboard or a mouse successfully and the default packet 500 * size and layout(in case of keyboard only) will be used, so it 501 * is ok to go ahead even if parsing of hid descriptor failed and 502 * we will not try to get the report descriptor. 503 */ 504 if (parse_hid_descr_error != HID_BAD_DESCR) { 505 /* 506 * Sun mouse rev 105 is a bit slow in responding to this 507 * request and requires multiple retries 508 */ 509 int retry; 510 511 /* 512 * Get and parse the report descriptor. 513 * Set the packet size if parsing is successful. 514 * Note that we start retry at 1 to have a delay 515 * in the first iteration. 516 */ 517 mutex_exit(&hidp->hid_mutex); 518 for (retry = 1; retry < HID_RETRY; retry++) { 519 if (hid_handle_report_descriptor(hidp, 520 hidp->hid_interfaceno) == USB_SUCCESS) { 521 break; 522 } 523 delay(retry * drv_usectohz(1000)); 524 } 525 if (retry >= HID_RETRY) { 526 527 goto fail; 528 } 529 mutex_enter(&hidp->hid_mutex); 530 531 /* 532 * If packet size is zero, but the device is identified 533 * as a mouse or a keyboard, use predefined packet 534 * size. 535 */ 536 if (hidp->hid_packet_size == 0) { 537 if (hidp->hid_if_descr.bInterfaceProtocol == 538 KEYBOARD_PROTOCOL) { 539 /* device is a keyboard */ 540 hidp->hid_packet_size = USBKPSZ; 541 } else if (hidp-> 542 hid_if_descr.bInterfaceProtocol == 543 MOUSE_PROTOCOL) { 544 /* device is a mouse */ 545 hidp->hid_packet_size = USBMSSZ; 546 } else { 547 USB_DPRINTF_L2(PRINT_MASK_ATTA, 548 hidp->hid_log_handle, 549 "Failed to find hid packet size"); 550 mutex_exit(&hidp->hid_mutex); 551 552 goto fail; 553 } 554 } 555 } 556 557 /* 558 * initialize the pipe policy for the interrupt pipe. 559 */ 560 hidp->hid_intr_pipe_policy.pp_max_async_reqs = 1; 561 562 /* 563 * Make a clas specific request to SET_IDLE 564 * In this case send no reports if state has not changed. 565 * See HID 7.2.4. 566 */ 567 mutex_exit(&hidp->hid_mutex); 568 hid_set_idle(hidp); 569 570 /* always initialize to report protocol */ 571 hid_set_protocol(hidp, SET_REPORT_PROTOCOL); 572 mutex_enter(&hidp->hid_mutex); 573 574 /* 575 * Create minor node based on information from the 576 * descriptors 577 */ 578 switch (hidp->hid_if_descr.bInterfaceProtocol) { 579 case KEYBOARD_PROTOCOL: 580 (void) strcpy(minor_name, "keyboard"); 581 582 break; 583 case MOUSE_PROTOCOL: 584 (void) strcpy(minor_name, "mouse"); 585 586 break; 587 default: 588 /* 589 * If the report descriptor has the GD mouse collection in 590 * its multiple collection, create a minor node and support it. 591 * It is used on some advanced keyboard/mouse set. 592 */ 593 if (hidparser_lookup_usage_collection( 594 hidp->hid_report_descr, HID_GENERIC_DESKTOP, 595 HID_GD_MOUSE) != HIDPARSER_FAILURE) { 596 (void) strcpy(minor_name, "mouse"); 597 598 break; 599 } 600 601 if (hidparser_get_top_level_collection_usage( 602 hidp->hid_report_descr, &usage_page, &usage) != 603 HIDPARSER_FAILURE) { 604 switch (usage_page) { 605 case HID_CONSUMER: 606 switch (usage) { 607 case HID_CONSUMER_CONTROL: 608 (void) strcpy(minor_name, 609 "consumer_control"); 610 611 break; 612 default: 613 (void) sprintf(minor_name, 614 "hid_%d_%d", usage_page, usage); 615 616 break; 617 } 618 619 break; 620 case HID_GENERIC_DESKTOP: 621 switch (usage) { 622 case HID_GD_POINTER: 623 (void) strcpy(minor_name, 624 "pointer"); 625 626 break; 627 case HID_GD_MOUSE: 628 (void) strcpy(minor_name, 629 "mouse"); 630 631 break; 632 case HID_GD_KEYBOARD: 633 (void) strcpy(minor_name, 634 "keyboard"); 635 636 break; 637 default: 638 (void) sprintf(minor_name, 639 "hid_%d_%d", usage_page, usage); 640 641 break; 642 } 643 644 break; 645 default: 646 (void) sprintf(minor_name, 647 "hid_%d_%d", usage_page, usage); 648 649 break; 650 } 651 } else { 652 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 653 "hid_attach: Unsupported HID device"); 654 mutex_exit(&hidp->hid_mutex); 655 656 goto fail; 657 } 658 659 break; 660 } 661 662 mutex_exit(&hidp->hid_mutex); 663 664 if ((ddi_create_minor_node(dip, minor_name, S_IFCHR, 665 HID_CONSTRUCT_EXTERNAL_MINOR(instance), 666 DDI_PSEUDO, 0)) != DDI_SUCCESS) { 667 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 668 "hid_attach: Could not create minor node"); 669 670 goto fail; 671 } 672 673 /* create internal path for virtual */ 674 if (strcmp(minor_name, "mouse") == 0) { 675 if (ddi_create_internal_pathname(dip, "internal_mouse", S_IFCHR, 676 HID_CONSTRUCT_INTERNAL_MINOR(instance)) != DDI_SUCCESS) { 677 678 goto fail; 679 } 680 } 681 682 if (strcmp(minor_name, "keyboard") == 0) { 683 if (ddi_create_internal_pathname(dip, "internal_keyboard", 684 S_IFCHR, HID_CONSTRUCT_INTERNAL_MINOR(instance)) != 685 DDI_SUCCESS) { 686 687 goto fail; 688 } 689 } 690 691 mutex_enter(&hidp->hid_mutex); 692 hidp->hid_attach_flags |= HID_MINOR_NODES; 693 hidp->hid_dev_state = USB_DEV_ONLINE; 694 mutex_exit(&hidp->hid_mutex); 695 696 /* register for all events */ 697 if (usb_register_event_cbs(dip, &hid_events, 0) != USB_SUCCESS) { 698 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 699 "usb_register_event_cbs failed"); 700 701 goto fail; 702 } 703 704 /* now create components to power manage this device */ 705 hid_create_pm_components(dip, hidp); 706 hid_pm_busy_component(hidp); 707 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 708 hid_pm_idle_component(hidp); 709 710 hidp->hid_internal_rq = hidp->hid_external_rq = NULL; 711 hidp->hid_internal_flag = hidp->hid_external_flag = 0; 712 hidp->hid_inuse_rq = NULL; 713 714 /* 715 * report device 716 */ 717 ddi_report_dev(dip); 718 719 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 720 "hid_attach: End"); 721 722 return (DDI_SUCCESS); 723 724 fail: 725 if (hidp) { 726 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 727 "hid_attach: fail"); 728 hid_detach_cleanup(dip, hidp); 729 } 730 731 return (DDI_FAILURE); 732 } 733 734 735 /* 736 * hid_detach : 737 * Gets called at the time of detach. 738 */ 739 static int 740 hid_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 741 { 742 int instance = ddi_get_instance(dip); 743 hid_state_t *hidp; 744 int rval = DDI_FAILURE; 745 746 hidp = ddi_get_soft_state(hid_statep, instance); 747 748 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, "hid_detach"); 749 750 switch (cmd) { 751 case DDI_DETACH: 752 /* 753 * Undo what we did in client_attach, freeing resources 754 * and removing things we installed. The system 755 * framework guarantees we are not active with this devinfo 756 * node in any other entry points at this time. 757 */ 758 hid_detach_cleanup(dip, hidp); 759 760 return (DDI_SUCCESS); 761 case DDI_SUSPEND: 762 rval = hid_cpr_suspend(hidp); 763 764 return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE); 765 default: 766 break; 767 } 768 769 return (rval); 770 } 771 772 /* 773 * hid_open : 774 * Open entry point: Opens the interrupt pipe. Sets up queues. 775 */ 776 /*ARGSUSED*/ 777 static int 778 hid_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) 779 { 780 int no_of_ep = 0; 781 int rval; 782 int instance; 783 hid_state_t *hidp; 784 minor_t minor = getminor(*devp); 785 786 instance = HID_MINOR_TO_INSTANCE(minor); 787 788 hidp = ddi_get_soft_state(hid_statep, instance); 789 if (hidp == NULL) { 790 791 return (ENXIO); 792 } 793 794 USB_DPRINTF_L4(PRINT_MASK_OPEN, hidp->hid_log_handle, 795 "hid_open: Begin"); 796 797 if (sflag) { 798 /* clone open NOT supported here */ 799 return (ENXIO); 800 } 801 802 if (!(flag & FREAD)) { 803 return (EIO); 804 } 805 806 /* 807 * This is a workaround: 808 * Currently, if we open an already disconnected device, and send 809 * a CONSOPENPOLL ioctl to it, the system will panic, please refer 810 * to the processing HID_OPEN_POLLED_INPUT ioctl in the routine 811 * hid_mctl_receive(). 812 * The consconfig_dacf module need this interface to detect if the 813 * device is already disconnnected. 814 */ 815 mutex_enter(&hidp->hid_mutex); 816 if (HID_IS_INTERNAL_OPEN(minor) && 817 (hidp->hid_dev_state == USB_DEV_DISCONNECTED)) { 818 mutex_exit(&hidp->hid_mutex); 819 return (ENODEV); 820 } 821 822 if (HID_IS_INTERNAL_OPEN(minor) && 823 (hidp->hid_internal_rq != NULL)) { 824 ASSERT(hidp->hid_internal_rq == q); 825 826 mutex_exit(&hidp->hid_mutex); 827 return (0); 828 } 829 830 if ((!HID_IS_INTERNAL_OPEN(minor)) && 831 (hidp->hid_external_rq != NULL)) { 832 ASSERT(hidp->hid_external_rq == q); 833 834 mutex_exit(&hidp->hid_mutex); 835 return (0); 836 } 837 838 mutex_exit(&hidp->hid_mutex); 839 840 q->q_ptr = hidp; 841 WR(q)->q_ptr = hidp; 842 843 mutex_enter(&hidp->hid_mutex); 844 if (hidp->hid_inuse_rq != NULL) { 845 /* Pipe has already been setup */ 846 847 if (HID_IS_INTERNAL_OPEN(minor)) { 848 hidp->hid_internal_flag = HID_STREAMS_OPEN; 849 hidp->hid_inuse_rq = hidp->hid_internal_rq = q; 850 } else { 851 hidp->hid_external_flag = HID_STREAMS_OPEN; 852 hidp->hid_inuse_rq = hidp->hid_external_rq = q; 853 } 854 855 mutex_exit(&hidp->hid_mutex); 856 857 qprocson(q); 858 859 return (0); 860 } 861 862 /* Pipe only needs to be opened once */ 863 hidp->hid_interrupt_pipe = NULL; 864 no_of_ep = hidp->hid_if_descr.bNumEndpoints; 865 mutex_exit(&hidp->hid_mutex); 866 867 /* Check if interrupt endpoint exists */ 868 if (no_of_ep > 0) { 869 /* Open the interrupt pipe */ 870 if (usb_pipe_xopen(hidp->hid_dip, 871 &hidp->hid_ep_intr_xdescr, 872 &hidp->hid_intr_pipe_policy, USB_FLAGS_SLEEP, 873 &hidp->hid_interrupt_pipe) != 874 USB_SUCCESS) { 875 876 q->q_ptr = NULL; 877 WR(q)->q_ptr = NULL; 878 return (EIO); 879 } 880 } 881 882 hid_pm_busy_component(hidp); 883 (void) pm_raise_power(hidp->hid_dip, 0, USB_DEV_OS_FULL_PWR); 884 885 mutex_enter(&hidp->hid_mutex); 886 if (HID_IS_INTERNAL_OPEN(minor)) { 887 hidp->hid_internal_flag = HID_STREAMS_OPEN; 888 hidp->hid_inuse_rq = hidp->hid_internal_rq = q; 889 } else { 890 hidp->hid_external_flag = HID_STREAMS_OPEN; 891 hidp->hid_inuse_rq = hidp->hid_external_rq = q; 892 } 893 894 mutex_exit(&hidp->hid_mutex); 895 896 qprocson(q); 897 898 mutex_enter(&hidp->hid_mutex); 899 900 if ((rval = hid_start_intr_polling(hidp)) != USB_SUCCESS) { 901 USB_DPRINTF_L2(PRINT_MASK_OPEN, hidp->hid_log_handle, 902 "unable to start intr pipe polling. rval = %d", rval); 903 904 if (HID_IS_INTERNAL_OPEN(minor)) 905 hidp->hid_internal_flag = HID_STREAMS_DISMANTLING; 906 else 907 hidp->hid_external_flag = HID_STREAMS_DISMANTLING; 908 mutex_exit(&hidp->hid_mutex); 909 910 usb_pipe_close(hidp->hid_dip, hidp->hid_interrupt_pipe, 911 USB_FLAGS_SLEEP, NULL, NULL); 912 913 mutex_enter(&hidp->hid_mutex); 914 hidp->hid_interrupt_pipe = NULL; 915 mutex_exit(&hidp->hid_mutex); 916 917 qprocsoff(q); 918 919 mutex_enter(&hidp->hid_mutex); 920 if (HID_IS_INTERNAL_OPEN(minor)) { 921 hidp->hid_internal_flag = 0; 922 hidp->hid_internal_rq = NULL; 923 if (hidp->hid_external_flag == HID_STREAMS_OPEN) 924 hidp->hid_inuse_rq = hidp->hid_external_rq; 925 else 926 hidp->hid_inuse_rq = NULL; 927 } else { 928 hidp->hid_external_flag = 0; 929 hidp->hid_external_rq = NULL; 930 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) 931 hidp->hid_inuse_rq = hidp->hid_internal_rq; 932 else 933 hidp->hid_inuse_rq = NULL; 934 } 935 mutex_exit(&hidp->hid_mutex); 936 937 q->q_ptr = NULL; 938 WR(q)->q_ptr = NULL; 939 940 hid_pm_idle_component(hidp); 941 942 return (EIO); 943 } 944 mutex_exit(&hidp->hid_mutex); 945 946 USB_DPRINTF_L4(PRINT_MASK_OPEN, hidp->hid_log_handle, "hid_open: End"); 947 948 /* 949 * Keyboard and mouse is Power managed by device activity. 950 * All other devices go busy on open and idle on close. 951 */ 952 switch (hidp->hid_pm->hid_pm_strategy) { 953 case HID_PM_ACTIVITY: 954 hid_pm_idle_component(hidp); 955 956 break; 957 default: 958 959 break; 960 } 961 962 return (0); 963 } 964 965 966 /* 967 * hid_close : 968 * Close entry point. 969 */ 970 /*ARGSUSED*/ 971 static int 972 hid_close(queue_t *q, int flag, cred_t *credp) 973 { 974 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 975 queue_t *wq; 976 mblk_t *mp; 977 978 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, "hid_close:"); 979 980 mutex_enter(&hidp->hid_mutex); 981 982 ASSERT((hidp->hid_internal_rq == q) || 983 (hidp->hid_external_rq == q)); 984 985 if (hidp->hid_internal_rq == q) 986 hidp->hid_internal_flag = HID_STREAMS_DISMANTLING; 987 else 988 hidp->hid_external_flag = HID_STREAMS_DISMANTLING; 989 990 mutex_exit(&hidp->hid_mutex); 991 992 /* 993 * In case there are any outstanding requests on 994 * the default pipe, wait forever for them to complete. 995 */ 996 (void) usb_pipe_drain_reqs(hidp->hid_dip, 997 hidp->hid_default_pipe, 0, USB_FLAGS_SLEEP, NULL, 0); 998 999 mutex_enter(&hidp->hid_mutex); 1000 wq = WR(q); 1001 /* drain any M_CTLS on the WQ */ 1002 while (mp = getq(wq)) { 1003 hid_qreply_merror(wq, mp, EIO); 1004 mutex_exit(&hidp->hid_mutex); 1005 hid_pm_idle_component(hidp); 1006 mutex_enter(&hidp->hid_mutex); 1007 } 1008 mutex_exit(&hidp->hid_mutex); 1009 1010 qprocsoff(q); 1011 1012 q->q_ptr = NULL; 1013 wq->q_ptr = NULL; 1014 1015 mutex_enter(&hidp->hid_mutex); 1016 1017 if (hidp->hid_internal_rq == q) { 1018 hidp->hid_internal_rq = NULL; 1019 hidp->hid_internal_flag = 0; 1020 if (hidp->hid_inuse_rq == q) { 1021 /* We are closing the active stream */ 1022 if (hidp->hid_external_flag == HID_STREAMS_OPEN) 1023 hidp->hid_inuse_rq = hidp->hid_external_rq; 1024 else 1025 hidp->hid_inuse_rq = NULL; 1026 } 1027 } else { 1028 hidp->hid_external_rq = NULL; 1029 hidp->hid_external_flag = 0; 1030 if (hidp->hid_inuse_rq == q) { 1031 /* We are closing the active stream */ 1032 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) 1033 hidp->hid_inuse_rq = hidp->hid_internal_rq; 1034 else 1035 hidp->hid_inuse_rq = NULL; 1036 } 1037 } 1038 1039 if (hidp->hid_inuse_rq != NULL) { 1040 mutex_exit(&hidp->hid_mutex); 1041 return (0); 1042 } 1043 1044 /* all queues are closed, close USB pipes */ 1045 hid_close_intr_pipe(hidp); 1046 mutex_exit(&hidp->hid_mutex); 1047 1048 /* 1049 * Devices other than keyboard/mouse go idle on close. 1050 */ 1051 switch (hidp->hid_pm->hid_pm_strategy) { 1052 case HID_PM_ACTIVITY: 1053 1054 break; 1055 default: 1056 hid_pm_idle_component(hidp); 1057 1058 break; 1059 } 1060 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 1061 "hid_close: End"); 1062 1063 return (0); 1064 } 1065 1066 1067 /* 1068 * hid_wput : 1069 * write put routine for the hid module 1070 */ 1071 static int 1072 hid_wput(queue_t *q, mblk_t *mp) 1073 { 1074 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 1075 int error = USB_SUCCESS; 1076 struct iocblk *iocbp; 1077 mblk_t *datap; 1078 int direction; 1079 struct copyresp *crp; 1080 queue_t *tmpq; 1081 int flag; 1082 1083 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1084 "hid_wput: Begin"); 1085 1086 /* See if the upper module is passing the right thing */ 1087 ASSERT(mp != NULL); 1088 ASSERT(mp->b_datap != NULL); 1089 1090 switch (mp->b_datap->db_type) { 1091 case M_FLUSH: /* Canonical flush handling */ 1092 if (*mp->b_rptr & FLUSHW) { 1093 flushq(q, FLUSHDATA); 1094 } 1095 1096 /* read queue not used so just send up */ 1097 if (*mp->b_rptr & FLUSHR) { 1098 *mp->b_rptr &= ~FLUSHW; 1099 qreply(q, mp); 1100 } else { 1101 freemsg(mp); 1102 } 1103 1104 break; 1105 case M_IOCTL: 1106 iocbp = (struct iocblk *)mp->b_rptr; 1107 1108 /* Only accept transparent ioctls */ 1109 if (iocbp->ioc_count != TRANSPARENT) { 1110 miocnak(q, mp, 0, EINVAL); 1111 break; 1112 } 1113 1114 switch (iocbp->ioc_cmd) { 1115 case HIDIOCKMGDIRECT: 1116 1117 mutex_enter(&hidp->hid_mutex); 1118 ASSERT(hidp->hid_inuse_rq != NULL); 1119 mutex_exit(&hidp->hid_mutex); 1120 1121 if ((datap = allocb(sizeof (int), BPRI_MED)) == NULL) { 1122 miocnak(q, mp, 0, ENOMEM); 1123 break; 1124 } 1125 1126 mutex_enter(&hidp->hid_mutex); 1127 if (hidp->hid_inuse_rq == hidp->hid_internal_rq) { 1128 *(int *)datap->b_wptr = 0; 1129 datap->b_wptr += sizeof (int); 1130 } else { 1131 ASSERT(hidp->hid_inuse_rq == 1132 hidp->hid_external_rq); 1133 *(int *)datap->b_wptr = 1; 1134 datap->b_wptr += sizeof (int); 1135 } 1136 mutex_exit(&hidp->hid_mutex); 1137 1138 mcopyout(mp, NULL, sizeof (int), NULL, datap); 1139 qreply(q, mp); 1140 break; 1141 1142 case HIDIOCKMSDIRECT: 1143 mcopyin(mp, NULL, sizeof (int), NULL); 1144 qreply(q, mp); 1145 break; 1146 1147 default: 1148 miocnak(q, mp, 0, ENOTTY); 1149 } 1150 1151 break; 1152 1153 case M_IOCDATA: 1154 1155 crp = (void *)mp->b_rptr; 1156 1157 if (crp->cp_rval != 0) { 1158 miocnak(q, mp, 0, EIO); 1159 break; 1160 } 1161 1162 switch (crp->cp_cmd) { 1163 case HIDIOCKMGDIRECT: 1164 miocack(q, mp, 0, 0); 1165 break; 1166 1167 case HIDIOCKMSDIRECT: 1168 direction = *(int *)mp->b_cont->b_rptr; 1169 1170 if ((direction != 0) && (direction != 1)) { 1171 miocnak(q, mp, 0, EINVAL); 1172 break; 1173 } 1174 1175 mutex_enter(&hidp->hid_mutex); 1176 1177 if (direction == 0) { 1178 /* The internal stream is made active */ 1179 flag = hidp->hid_internal_flag; 1180 tmpq = hidp->hid_internal_rq; 1181 } else { 1182 /* The external stream is made active */ 1183 flag = hidp->hid_external_flag; 1184 tmpq = hidp->hid_external_rq; 1185 } 1186 1187 if (flag != HID_STREAMS_OPEN) { 1188 mutex_exit(&hidp->hid_mutex); 1189 miocnak(q, mp, 0, EIO); 1190 break; 1191 } 1192 1193 hidp->hid_inuse_rq = tmpq; 1194 1195 mutex_exit(&hidp->hid_mutex); 1196 miocack(q, mp, 0, 0); 1197 break; 1198 1199 default: 1200 miocnak(q, mp, 0, ENOTTY); 1201 break; 1202 } 1203 1204 break; 1205 1206 case M_CTL: 1207 /* we are busy now */ 1208 hid_pm_busy_component(hidp); 1209 1210 if (q->q_first) { 1211 (void) putq(q, mp); 1212 } else { 1213 error = hid_mctl_receive(q, mp); 1214 switch (error) { 1215 case HID_ENQUEUE: 1216 /* 1217 * put this mblk on the WQ for the wsrv to 1218 * process 1219 */ 1220 (void) putq(q, mp); 1221 1222 break; 1223 case HID_INPROGRESS: 1224 /* request has been queued to the device */ 1225 1226 break; 1227 case HID_SUCCESS: 1228 /* 1229 * returned by M_CTLS that are processed 1230 * immediately 1231 */ 1232 1233 /* FALLTHRU */ 1234 case HID_FAILURE: 1235 default: 1236 hid_pm_idle_component(hidp); 1237 break; 1238 } 1239 } 1240 break; 1241 default: 1242 hid_qreply_merror(q, mp, EINVAL); 1243 error = USB_FAILURE; 1244 break; 1245 } 1246 1247 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1248 "hid_wput: End"); 1249 1250 return (DDI_SUCCESS); 1251 } 1252 1253 1254 /* 1255 * hid_wsrv : 1256 * Write service routine for hid. When a message arrives through 1257 * hid_wput(), it is kept in write queue to be serviced later. 1258 */ 1259 static int 1260 hid_wsrv(queue_t *q) 1261 { 1262 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 1263 int error; 1264 mblk_t *mp; 1265 1266 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1267 "hid_wsrv: Begin"); 1268 1269 mutex_enter(&hidp->hid_mutex); 1270 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1271 "hid_wsrv: dev_state: %s", 1272 usb_str_dev_state(hidp->hid_dev_state)); 1273 1274 /* 1275 * raise power if we are powered down. It is OK to block here since 1276 * we have a separate thread to process this STREAM 1277 */ 1278 if (hidp->hid_dev_state == USB_DEV_PWRED_DOWN) { 1279 mutex_exit(&hidp->hid_mutex); 1280 (void) pm_raise_power(hidp->hid_dip, 0, USB_DEV_OS_FULL_PWR); 1281 mutex_enter(&hidp->hid_mutex); 1282 } 1283 1284 /* 1285 * continue servicing all the M_CTL's till the queue is empty 1286 * or the device gets disconnected or till a hid_close() 1287 */ 1288 while ((hidp->hid_dev_state == USB_DEV_ONLINE) && 1289 (HID_STREAMS_FLAG(q, hidp) != HID_STREAMS_DISMANTLING) && 1290 ((mp = getq(q)) != NULL)) { 1291 1292 /* Send a message down */ 1293 mutex_exit(&hidp->hid_mutex); 1294 error = hid_mctl_receive(q, mp); 1295 switch (error) { 1296 case HID_ENQUEUE: 1297 /* put this mblk back on q to preserve order */ 1298 (void) putbq(q, mp); 1299 1300 break; 1301 case HID_INPROGRESS: 1302 /* request has been queued to the device */ 1303 1304 break; 1305 case HID_SUCCESS: 1306 case HID_FAILURE: 1307 default: 1308 hid_pm_idle_component(hidp); 1309 1310 break; 1311 } 1312 mutex_enter(&hidp->hid_mutex); 1313 } 1314 mutex_exit(&hidp->hid_mutex); 1315 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1316 "hid_wsrv: End"); 1317 1318 return (DDI_SUCCESS); 1319 } 1320 1321 1322 /* 1323 * hid_power: 1324 * power entry point 1325 */ 1326 static int 1327 hid_power(dev_info_t *dip, int comp, int level) 1328 { 1329 int instance = ddi_get_instance(dip); 1330 hid_state_t *hidp; 1331 hid_power_t *hidpm; 1332 int retval; 1333 1334 hidp = ddi_get_soft_state(hid_statep, instance); 1335 1336 USB_DPRINTF_L3(PRINT_MASK_PM, hidp->hid_log_handle, "hid_power:" 1337 " hid_state: comp=%d level=%d", comp, level); 1338 1339 /* check if we are transitioning to a legal power level */ 1340 mutex_enter(&hidp->hid_mutex); 1341 hidpm = hidp->hid_pm; 1342 1343 if (USB_DEV_PWRSTATE_OK(hidpm->hid_pwr_states, level)) { 1344 1345 USB_DPRINTF_L2(PRINT_MASK_PM, hidp->hid_log_handle, 1346 "hid_power: illegal level=%d hid_pwr_states=%d", 1347 level, hidpm->hid_pwr_states); 1348 1349 mutex_exit(&hidp->hid_mutex); 1350 1351 return (DDI_FAILURE); 1352 } 1353 1354 switch (level) { 1355 case USB_DEV_OS_PWR_OFF: 1356 retval = hid_pwrlvl0(hidp); 1357 break; 1358 case USB_DEV_OS_PWR_1: 1359 retval = hid_pwrlvl1(hidp); 1360 break; 1361 case USB_DEV_OS_PWR_2: 1362 retval = hid_pwrlvl2(hidp); 1363 break; 1364 case USB_DEV_OS_FULL_PWR: 1365 retval = hid_pwrlvl3(hidp); 1366 break; 1367 default: 1368 retval = USB_FAILURE; 1369 break; 1370 } 1371 1372 mutex_exit(&hidp->hid_mutex); 1373 1374 return ((retval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 1375 } 1376 1377 1378 /* 1379 * hid_interrupt_pipe_callback: 1380 * Callback function for the hid intr pipe. This function is called by 1381 * USBA when a buffer has been filled. This driver does not cook the data, 1382 * it just sends the message up. 1383 */ 1384 static void 1385 hid_interrupt_pipe_callback(usb_pipe_handle_t pipe, usb_intr_req_t *req) 1386 { 1387 hid_state_t *hidp = (hid_state_t *)req->intr_client_private; 1388 queue_t *q; 1389 1390 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1391 "hid_interrupt_pipe_callback: ph = 0x%p req = 0x%p", 1392 (void *)pipe, (void *)req); 1393 1394 hid_pm_busy_component(hidp); 1395 1396 mutex_enter(&hidp->hid_mutex); 1397 1398 /* 1399 * If hid_close() is in progress, we shouldn't try accessing queue 1400 * Otherwise indicate that a putnext is going to happen, so 1401 * if close after this, that should wait for the putnext to finish. 1402 */ 1403 if (HID_STREAMS_FLAG(hidp->hid_inuse_rq, hidp) == 1404 HID_STREAMS_OPEN) { 1405 /* 1406 * Check if data can be put to the next queue. 1407 */ 1408 if (!canputnext(hidp->hid_inuse_rq)) { 1409 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1410 "Buffer flushed when overflowed."); 1411 1412 /* Flush the queue above */ 1413 hid_flush(hidp->hid_inuse_rq); 1414 mutex_exit(&hidp->hid_mutex); 1415 } else { 1416 q = hidp->hid_inuse_rq; 1417 mutex_exit(&hidp->hid_mutex); 1418 1419 /* Put data upstream */ 1420 putnext(q, req->intr_data); 1421 1422 /* usb_free_intr_req should not free data */ 1423 req->intr_data = NULL; 1424 } 1425 } else { 1426 mutex_exit(&hidp->hid_mutex); 1427 } 1428 1429 /* free request and data */ 1430 usb_free_intr_req(req); 1431 hid_pm_idle_component(hidp); 1432 } 1433 1434 1435 /* 1436 * hid_default_pipe_callback : 1437 * Callback routine for the asynchronous control transfer 1438 * Called from hid_send_async_ctrl_request() where we open 1439 * the pipe in exclusive mode 1440 */ 1441 static void 1442 hid_default_pipe_callback(usb_pipe_handle_t pipe, usb_ctrl_req_t *req) 1443 { 1444 hid_default_pipe_arg_t *hid_default_pipe_arg = 1445 (hid_default_pipe_arg_t *)req->ctrl_client_private; 1446 queue_t *wq = hid_default_pipe_arg->hid_default_pipe_arg_queue; 1447 queue_t *rq = RD(wq); 1448 hid_state_t *hidp = (hid_state_t *)rq->q_ptr; 1449 mblk_t *mctl_mp; 1450 mblk_t *data = NULL; 1451 1452 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1453 "hid_default_pipe_callback: " 1454 "ph = 0x%p, req = 0x%p, data= 0x%p", 1455 (void *)pipe, (void *)req, (void *)data); 1456 1457 ASSERT((req->ctrl_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1458 1459 if (req->ctrl_data) { 1460 data = req->ctrl_data; 1461 req->ctrl_data = NULL; 1462 } 1463 1464 /* 1465 * Free the b_cont of the original message that was sent down. 1466 */ 1467 mctl_mp = hid_default_pipe_arg->hid_default_pipe_arg_mblk; 1468 freemsg(mctl_mp->b_cont); 1469 1470 /* chain the mblk received to the original & send it up */ 1471 mctl_mp->b_cont = data; 1472 1473 if (canputnext(rq)) { 1474 putnext(rq, mctl_mp); 1475 } else { 1476 freemsg(mctl_mp); /* avoid leak */ 1477 } 1478 1479 /* 1480 * Free the argument for the asynchronous callback 1481 */ 1482 kmem_free(hid_default_pipe_arg, sizeof (hid_default_pipe_arg_t)); 1483 1484 /* 1485 * Free the control pipe request structure. 1486 */ 1487 usb_free_ctrl_req(req); 1488 1489 mutex_enter(&hidp->hid_mutex); 1490 hidp->hid_default_pipe_req--; 1491 ASSERT(hidp->hid_default_pipe_req >= 0); 1492 mutex_exit(&hidp->hid_mutex); 1493 1494 hid_pm_idle_component(hidp); 1495 qenable(wq); 1496 } 1497 1498 1499 /* 1500 * hid_interrupt_pipe_exception_callback: 1501 * Exception callback routine for interrupt pipe. If there is any data, 1502 * destroy it. No threads are waiting for the exception callback. 1503 */ 1504 /*ARGSUSED*/ 1505 static void 1506 hid_interrupt_pipe_exception_callback(usb_pipe_handle_t pipe, 1507 usb_intr_req_t *req) 1508 { 1509 hid_state_t *hidp = (hid_state_t *)req->intr_client_private; 1510 mblk_t *data = req->intr_data; 1511 usb_cb_flags_t flags = req->intr_cb_flags; 1512 int rval; 1513 1514 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1515 "hid_interrupt_pipe_exception_callback: " 1516 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x", 1517 req->intr_completion_reason, (void *)data, req->intr_cb_flags); 1518 1519 ASSERT((req->intr_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1520 1521 if (((flags & USB_CB_FUNCTIONAL_STALL) != 0) && 1522 ((flags & USB_CB_STALL_CLEARED) == 0)) { 1523 USB_DPRINTF_L2(PRINT_MASK_ALL, 1524 hidp->hid_log_handle, 1525 "hid_interrupt_pipe_exception_callback: " 1526 "unable to clear stall. flags = 0x%x", 1527 req->intr_cb_flags); 1528 } 1529 1530 mutex_enter(&hidp->hid_mutex); 1531 1532 switch (req->intr_completion_reason) { 1533 case USB_CR_STOPPED_POLLING: 1534 case USB_CR_PIPE_CLOSING: 1535 default: 1536 1537 break; 1538 case USB_CR_PIPE_RESET: 1539 case USB_CR_NO_RESOURCES: 1540 if ((hidp->hid_dev_state == USB_DEV_ONLINE) && 1541 ((rval = hid_start_intr_polling(hidp)) != 1542 USB_SUCCESS)) { 1543 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1544 "unable to restart interrupt poll. rval = %d", 1545 rval); 1546 } 1547 1548 break; 1549 } 1550 1551 mutex_exit(&hidp->hid_mutex); 1552 1553 usb_free_intr_req(req); 1554 } 1555 1556 1557 /* 1558 * hid_default_pipe_exception_callback: 1559 * Exception callback routine for default pipe. 1560 */ 1561 /*ARGSUSED*/ 1562 static void 1563 hid_default_pipe_exception_callback(usb_pipe_handle_t pipe, 1564 usb_ctrl_req_t *req) 1565 { 1566 hid_default_pipe_arg_t *hid_default_pipe_arg = 1567 (hid_default_pipe_arg_t *)req->ctrl_client_private; 1568 queue_t *wq = hid_default_pipe_arg->hid_default_pipe_arg_queue; 1569 queue_t *rq = RD(wq); 1570 hid_state_t *hidp = (hid_state_t *)rq->q_ptr; 1571 usb_cr_t ctrl_completion_reason = req->ctrl_completion_reason; 1572 mblk_t *mp, *data = NULL; 1573 1574 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1575 "hid_default_pipe_exception_callback: " 1576 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x", 1577 ctrl_completion_reason, (void *)data, req->ctrl_cb_flags); 1578 1579 ASSERT((req->ctrl_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1580 1581 mp = hid_default_pipe_arg->hid_default_pipe_arg_mblk; 1582 1583 /* 1584 * Pass an error message up. Reuse existing mblk. 1585 */ 1586 if (canputnext(rq)) { 1587 mp->b_datap->db_type = M_ERROR; 1588 mp->b_rptr = mp->b_datap->db_base; 1589 mp->b_wptr = mp->b_rptr + sizeof (char); 1590 *mp->b_rptr = EIO; 1591 putnext(rq, mp); 1592 } else { 1593 freemsg(mp); 1594 } 1595 1596 kmem_free(hid_default_pipe_arg, sizeof (hid_default_pipe_arg_t)); 1597 1598 mutex_enter(&hidp->hid_mutex); 1599 hidp->hid_default_pipe_req--; 1600 ASSERT(hidp->hid_default_pipe_req >= 0); 1601 mutex_exit(&hidp->hid_mutex); 1602 1603 qenable(wq); 1604 usb_free_ctrl_req(req); 1605 hid_pm_idle_component(hidp); 1606 } 1607 1608 1609 /* 1610 * event handling: 1611 * 1612 * hid_reconnect_event_callback: 1613 * the device was disconnected but this instance not detached, probably 1614 * because the device was busy 1615 * 1616 * If the same device, continue with restoring state 1617 */ 1618 static int 1619 hid_restore_state_event_callback(dev_info_t *dip) 1620 { 1621 hid_state_t *hidp = (hid_state_t *)ddi_get_soft_state(hid_statep, 1622 ddi_get_instance(dip)); 1623 1624 ASSERT(hidp != NULL); 1625 1626 USB_DPRINTF_L3(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1627 "hid_restore_state_event_callback: dip=0x%p", (void *)dip); 1628 1629 hid_restore_device_state(dip, hidp); 1630 1631 return (USB_SUCCESS); 1632 } 1633 1634 1635 /* 1636 * hid_cpr_suspend 1637 * Fail suspend if we can't finish outstanding i/o activity. 1638 */ 1639 static int 1640 hid_cpr_suspend(hid_state_t *hidp) 1641 { 1642 int rval, prev_state; 1643 int retval = USB_FAILURE; 1644 1645 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1646 "hid_cpr_suspend: dip=0x%p", (void *)hidp->hid_dip); 1647 1648 mutex_enter(&hidp->hid_mutex); 1649 switch (hidp->hid_dev_state) { 1650 case USB_DEV_ONLINE: 1651 case USB_DEV_PWRED_DOWN: 1652 prev_state = hidp->hid_dev_state; 1653 hidp->hid_dev_state = USB_DEV_SUSPENDED; 1654 mutex_exit(&hidp->hid_mutex); 1655 1656 /* drain all request outstanding on the default control pipe */ 1657 rval = usb_pipe_drain_reqs(hidp->hid_dip, 1658 hidp->hid_default_pipe, hid_default_pipe_drain_timeout, 1659 USB_FLAGS_SLEEP, NULL, 0); 1660 1661 /* fail checkpoint if we haven't finished the job yet */ 1662 mutex_enter(&hidp->hid_mutex); 1663 if ((rval != USB_SUCCESS) || (hidp->hid_default_pipe_req > 0)) { 1664 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1665 "hid_cpr_suspend: " 1666 "device busy - can't checkpoint"); 1667 1668 /* fall back to previous state */ 1669 hidp->hid_dev_state = prev_state; 1670 } else { 1671 retval = USB_SUCCESS; 1672 hid_save_device_state(hidp); 1673 } 1674 1675 break; 1676 case USB_DEV_DISCONNECTED: 1677 hidp->hid_dev_state = USB_DEV_SUSPENDED; 1678 hid_save_device_state(hidp); 1679 retval = USB_SUCCESS; 1680 break; 1681 case USB_DEV_SUSPENDED: 1682 default: 1683 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1684 "hid_cpr_suspend: Illegal dev state: %d", 1685 hidp->hid_dev_state); 1686 1687 break; 1688 } 1689 mutex_exit(&hidp->hid_mutex); 1690 1691 return (retval); 1692 } 1693 1694 1695 static void 1696 hid_cpr_resume(hid_state_t *hidp) 1697 { 1698 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1699 "hid_cpr_resume: dip=0x%p", (void *)hidp->hid_dip); 1700 1701 hid_restore_device_state(hidp->hid_dip, hidp); 1702 } 1703 1704 1705 /* 1706 * hid_disconnect_event_callback: 1707 * The device has been disconnected. We either wait for 1708 * detach or a reconnect event. Close all pipes and timeouts. 1709 */ 1710 static int 1711 hid_disconnect_event_callback(dev_info_t *dip) 1712 { 1713 hid_state_t *hidp; 1714 mblk_t *mp; 1715 1716 hidp = (hid_state_t *)ddi_get_soft_state(hid_statep, 1717 ddi_get_instance(dip)); 1718 ASSERT(hidp != NULL); 1719 1720 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1721 "hid_disconnect_event_callback: dip=0x%p", (void *)dip); 1722 1723 mutex_enter(&hidp->hid_mutex); 1724 switch (hidp->hid_dev_state) { 1725 case USB_DEV_ONLINE: 1726 case USB_DEV_PWRED_DOWN: 1727 hidp->hid_dev_state = USB_DEV_DISCONNECTED; 1728 if (HID_IS_OPEN(hidp)) { 1729 1730 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1731 "busy device has been disconnected"); 1732 } 1733 hid_save_device_state(hidp); 1734 1735 /* 1736 * Notify applications about device removal, this only 1737 * applies to an external (aka. physical) open. For an 1738 * internal open, consconfig_dacf closes the queue. 1739 */ 1740 if (hidp->hid_external_flag == HID_STREAMS_OPEN) { 1741 queue_t *q = hidp->hid_external_rq; 1742 mutex_exit(&hidp->hid_mutex); 1743 mp = allocb(sizeof (uchar_t), BPRI_HI); 1744 if (mp != NULL) { 1745 mp->b_datap->db_type = M_ERROR; 1746 mp->b_rptr = mp->b_datap->db_base; 1747 mp->b_wptr = mp->b_rptr + sizeof (char); 1748 *mp->b_rptr = ENODEV; 1749 putnext(q, mp); 1750 } 1751 mutex_enter(&hidp->hid_mutex); 1752 } 1753 1754 break; 1755 case USB_DEV_SUSPENDED: 1756 /* we remain suspended */ 1757 1758 break; 1759 default: 1760 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1761 "hid_disconnect_event_callback: Illegal dev state: %d", 1762 hidp->hid_dev_state); 1763 1764 break; 1765 } 1766 mutex_exit(&hidp->hid_mutex); 1767 1768 return (USB_SUCCESS); 1769 } 1770 1771 1772 /* 1773 * hid_power_change_callback: 1774 * Async callback function to notify pm_raise_power completion 1775 * after hid_power entry point is called. 1776 */ 1777 static void 1778 hid_power_change_callback(void *arg, int rval) 1779 { 1780 hid_state_t *hidp; 1781 queue_t *wq; 1782 1783 hidp = (hid_state_t *)arg; 1784 1785 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 1786 "hid_power_change_callback - rval: %d", rval); 1787 1788 mutex_enter(&hidp->hid_mutex); 1789 hidp->hid_pm->hid_raise_power = B_FALSE; 1790 1791 if (hidp->hid_dev_state == USB_DEV_ONLINE) { 1792 wq = WR(hidp->hid_inuse_rq); 1793 mutex_exit(&hidp->hid_mutex); 1794 1795 qenable(wq); 1796 1797 } else { 1798 mutex_exit(&hidp->hid_mutex); 1799 } 1800 } 1801 1802 1803 /* 1804 * hid_parse_hid_descr: 1805 * Parse the hid descriptor, check after interface and after 1806 * endpoint descriptor 1807 */ 1808 static size_t 1809 hid_parse_hid_descr(usb_hid_descr_t *ret_descr, size_t ret_buf_len, 1810 usb_alt_if_data_t *altif_data, usb_ep_data_t *ep_data) 1811 { 1812 usb_cvs_data_t *cvs; 1813 int which_cvs; 1814 1815 for (which_cvs = 0; which_cvs < altif_data->altif_n_cvs; which_cvs++) { 1816 cvs = &altif_data->altif_cvs[which_cvs]; 1817 if (cvs->cvs_buf == NULL) { 1818 continue; 1819 } 1820 if (cvs->cvs_buf[1] == USB_DESCR_TYPE_HID) { 1821 return (usb_parse_data("ccscccs", 1822 cvs->cvs_buf, cvs->cvs_buf_len, 1823 (void *)ret_descr, 1824 (size_t)ret_buf_len)); 1825 } 1826 } 1827 1828 /* now try after endpoint */ 1829 for (which_cvs = 0; which_cvs < ep_data->ep_n_cvs; which_cvs++) { 1830 cvs = &ep_data->ep_cvs[which_cvs]; 1831 if (cvs->cvs_buf == NULL) { 1832 continue; 1833 } 1834 if (cvs->cvs_buf[1] == USB_DESCR_TYPE_HID) { 1835 return (usb_parse_data("ccscccs", 1836 cvs->cvs_buf, cvs->cvs_buf_len, 1837 (void *)ret_descr, 1838 (size_t)ret_buf_len)); 1839 } 1840 } 1841 1842 return (USB_PARSE_ERROR); 1843 } 1844 1845 1846 /* 1847 * hid_parse_hid_descr_failure: 1848 * If parsing of hid descriptor failed and the device is 1849 * a keyboard or mouse, use predefined length and packet size. 1850 */ 1851 static int 1852 hid_parse_hid_descr_failure(hid_state_t *hidp) 1853 { 1854 /* 1855 * Parsing hid descriptor failed, probably because the 1856 * device did not return a valid hid descriptor. Check to 1857 * see if this is a keyboard or mouse. If so, use the 1858 * predefined hid descriptor length and packet size. 1859 * Otherwise, detach and return failure. 1860 */ 1861 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 1862 "Parsing of hid descriptor failed"); 1863 1864 if (hidp->hid_if_descr.bInterfaceProtocol == KEYBOARD_PROTOCOL) { 1865 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1866 "Set hid descriptor length to predefined " 1867 "USB_KB_HID_DESCR_LENGTH for keyboard."); 1868 1869 /* device is a keyboard */ 1870 hidp->hid_hid_descr.wReportDescriptorLength = 1871 USB_KB_HID_DESCR_LENGTH; 1872 1873 hidp->hid_packet_size = USBKPSZ; 1874 1875 } else if (hidp->hid_if_descr.bInterfaceProtocol == 1876 MOUSE_PROTOCOL) { 1877 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1878 "Set hid descriptor length to predefined " 1879 "USB_MS_HID_DESCR_LENGTH for mouse."); 1880 1881 /* device is a mouse */ 1882 hidp->hid_hid_descr.wReportDescriptorLength = 1883 USB_MS_HID_DESCR_LENGTH; 1884 1885 hidp->hid_packet_size = USBMSSZ; 1886 } else { 1887 1888 return (USB_FAILURE); 1889 } 1890 1891 return (USB_SUCCESS); 1892 } 1893 1894 1895 /* 1896 * hid_handle_report_descriptor: 1897 * Get the report descriptor, call hidparser routine to parse 1898 * it and query the hidparser tree to get the packet size 1899 */ 1900 static int 1901 hid_handle_report_descriptor(hid_state_t *hidp, int interface) 1902 { 1903 usb_cr_t completion_reason; 1904 usb_cb_flags_t cb_flags; 1905 mblk_t *data = NULL; 1906 hidparser_packet_info_t hpack; 1907 int i; 1908 usb_ctrl_setup_t setup = { 1909 USB_DEV_REQ_DEV_TO_HOST | /* bmRequestType */ 1910 USB_DEV_REQ_RCPT_IF, 1911 USB_REQ_GET_DESCR, /* bRequest */ 1912 USB_CLASS_DESCR_TYPE_REPORT, /* wValue */ 1913 0, /* wIndex: interface, fill in later */ 1914 0, /* wLength, fill in later */ 1915 0 /* attributes */ 1916 }; 1917 1918 /* 1919 * Parsing hid desciptor was successful earlier. 1920 * Get Report Descriptor 1921 */ 1922 setup.wIndex = (uint16_t)interface; 1923 setup.wLength = hidp->hid_hid_descr.wReportDescriptorLength; 1924 if (usb_pipe_ctrl_xfer_wait(hidp->hid_default_pipe, 1925 &setup, 1926 &data, /* data */ 1927 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 1928 1929 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1930 "Failed to receive the Report Descriptor"); 1931 freemsg(data); 1932 1933 return (USB_FAILURE); 1934 1935 } else { 1936 int n = hidp->hid_hid_descr.wReportDescriptorLength; 1937 1938 ASSERT(data); 1939 1940 /* Print the report descriptor */ 1941 for (i = 0; i < n; i++) { 1942 USB_DPRINTF_L3(PRINT_MASK_ATTA, hidp->hid_log_handle, 1943 "Index = %d\tvalue =0x%x", i, 1944 (int)(data->b_rptr[i])); 1945 } 1946 1947 /* Get Report Descriptor was successful */ 1948 if (hidparser_parse_report_descriptor( 1949 data->b_rptr, 1950 hidp->hid_hid_descr.wReportDescriptorLength, 1951 &hidp->hid_hid_descr, 1952 &hidp->hid_report_descr) == HIDPARSER_SUCCESS) { 1953 1954 /* find max intr-in xfer length */ 1955 hidparser_find_max_packet_size_from_report_descriptor( 1956 hidp->hid_report_descr, &hpack); 1957 /* round up to the nearest byte */ 1958 hidp->hid_packet_size = (hpack.max_packet_size + 7) / 8; 1959 1960 /* if report id is used, add more more byte for it */ 1961 if (hpack.report_id != HID_REPORT_ID_UNDEFINED) { 1962 hidp->hid_packet_size++; 1963 } 1964 } else { 1965 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 1966 "Invalid Report Descriptor"); 1967 freemsg(data); 1968 1969 return (USB_FAILURE); 1970 } 1971 1972 freemsg(data); 1973 1974 return (USB_SUCCESS); 1975 } 1976 } 1977 1978 1979 /* 1980 * hid_set_idle: 1981 * Make a clas specific request to SET_IDLE. 1982 * In this case send no reports if state has not changed. 1983 * See HID 7.2.4. 1984 */ 1985 /*ARGSUSED*/ 1986 static void 1987 hid_set_idle(hid_state_t *hidp) 1988 { 1989 usb_cr_t completion_reason; 1990 usb_cb_flags_t cb_flags; 1991 usb_ctrl_setup_t setup = { 1992 USB_DEV_REQ_HOST_TO_DEV | /* bmRequestType */ 1993 USB_DEV_REQ_TYPE_CLASS | 1994 USB_DEV_REQ_RCPT_IF, 1995 SET_IDLE, /* bRequest */ 1996 DURATION, /* wValue */ 1997 0, /* wIndex: interface, fill in later */ 1998 0, /* wLength */ 1999 0 /* attributes */ 2000 }; 2001 2002 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2003 "hid_set_idle: Begin"); 2004 2005 setup.wIndex = hidp->hid_if_descr.bInterfaceNumber; 2006 if (usb_pipe_ctrl_xfer_wait( 2007 hidp->hid_default_pipe, 2008 &setup, 2009 NULL, /* no data to send. */ 2010 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 2011 2012 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 2013 "Failed while trying to set idle," 2014 "cr = %d, cb_flags = 0x%x\n", 2015 completion_reason, cb_flags); 2016 } 2017 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2018 "hid_set_idle: End"); 2019 } 2020 2021 2022 /* 2023 * hid_set_protocol: 2024 * Initialize the device to set the preferred protocol 2025 */ 2026 /*ARGSUSED*/ 2027 static void 2028 hid_set_protocol(hid_state_t *hidp, int protocol) 2029 { 2030 usb_cr_t completion_reason; 2031 usb_cb_flags_t cb_flags; 2032 usb_ctrl_setup_t setup; 2033 2034 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2035 "hid_set_protocol(%d): Begin", protocol); 2036 2037 /* initialize the setup request */ 2038 setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV | 2039 USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; 2040 setup.bRequest = SET_PROTOCOL; 2041 setup.wValue = (uint16_t)protocol; 2042 setup.wIndex = hidp->hid_if_descr.bInterfaceNumber; 2043 setup.wLength = 0; 2044 setup.attrs = 0; 2045 if (usb_pipe_ctrl_xfer_wait( 2046 hidp->hid_default_pipe, /* bmRequestType */ 2047 &setup, 2048 NULL, /* no data to send */ 2049 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 2050 /* 2051 * Some devices fail to follow the specification 2052 * and instead of STALLing, they continously 2053 * NAK the SET_IDLE command. We need to reset 2054 * the pipe then, so that ohci doesn't panic. 2055 */ 2056 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 2057 "Failed while trying to set protocol:%d," 2058 "cr = %d cb_flags = 0x%x\n", 2059 completion_reason, cb_flags, protocol); 2060 } 2061 2062 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2063 "hid_set_protocol: End"); 2064 } 2065 2066 2067 /* 2068 * hid_detach_cleanup: 2069 * called by attach and detach for cleanup. 2070 */ 2071 static void 2072 hid_detach_cleanup(dev_info_t *dip, hid_state_t *hidp) 2073 { 2074 int flags = hidp->hid_attach_flags; 2075 int rval; 2076 hid_power_t *hidpm; 2077 2078 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2079 "hid_detach_cleanup: Begin"); 2080 2081 if ((hidp->hid_attach_flags & HID_LOCK_INIT) == 0) { 2082 2083 goto done; 2084 } 2085 2086 /* 2087 * Disable the event callbacks first, after this point, event 2088 * callbacks will never get called. Note we shouldn't hold 2089 * mutex while unregistering events because there may be a 2090 * competing event callback thread. Event callbacks are done 2091 * with ndi mutex held and this can cause a potential deadlock. 2092 */ 2093 usb_unregister_event_cbs(dip, &hid_events); 2094 2095 mutex_enter(&hidp->hid_mutex); 2096 2097 hidpm = hidp->hid_pm; 2098 2099 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 2100 "hid_detach_cleanup: hidpm=0x%p", (void *)hidpm); 2101 2102 if (hidpm && (hidp->hid_dev_state != USB_DEV_DISCONNECTED)) { 2103 2104 mutex_exit(&hidp->hid_mutex); 2105 hid_pm_busy_component(hidp); 2106 if (hid_is_pm_enabled(dip) == USB_SUCCESS) { 2107 2108 if (hidpm->hid_wakeup_enabled) { 2109 2110 /* First bring the device to full power */ 2111 (void) pm_raise_power(dip, 0, 2112 USB_DEV_OS_FULL_PWR); 2113 2114 /* Disable remote wakeup */ 2115 rval = usb_handle_remote_wakeup(dip, 2116 USB_REMOTE_WAKEUP_DISABLE); 2117 2118 if (rval != DDI_SUCCESS) { 2119 USB_DPRINTF_L2(PRINT_MASK_ALL, 2120 hidp->hid_log_handle, 2121 "hid_detach_cleanup: " 2122 "disble remote wakeup failed, " 2123 "rval= %d", rval); 2124 } 2125 } 2126 2127 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF); 2128 } 2129 hid_pm_idle_component(hidp); 2130 mutex_enter(&hidp->hid_mutex); 2131 } 2132 2133 if (hidpm) { 2134 freemsg(hidpm->hid_pm_pwrup); 2135 kmem_free(hidpm, sizeof (hid_power_t)); 2136 hidp->hid_pm = NULL; 2137 } 2138 2139 mutex_exit(&hidp->hid_mutex); 2140 2141 if (hidp->hid_report_descr != NULL) { 2142 (void) hidparser_free_report_descriptor_handle( 2143 hidp->hid_report_descr); 2144 } 2145 2146 if (flags & HID_MINOR_NODES) { 2147 ddi_remove_minor_node(dip, NULL); 2148 } 2149 2150 mutex_destroy(&hidp->hid_mutex); 2151 2152 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2153 "hid_detach_cleanup: End"); 2154 2155 done: 2156 usb_client_detach(dip, hidp->hid_dev_data); 2157 usb_free_log_hdl(hidp->hid_log_handle); 2158 ddi_soft_state_free(hid_statep, hidp->hid_instance); 2159 2160 ddi_prop_remove_all(dip); 2161 } 2162 2163 2164 /* 2165 * hid_start_intr_polling: 2166 * Allocate an interrupt request structure, initialize, 2167 * and start interrupt transfers. 2168 */ 2169 static int 2170 hid_start_intr_polling(hid_state_t *hidp) 2171 { 2172 usb_intr_req_t *req; 2173 int rval = USB_SUCCESS; 2174 2175 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2176 "hid_start_intr_polling: " 2177 "dev_state=%s internal_str_flag=%d external_str_flag=%d ph=0x%p", 2178 usb_str_dev_state(hidp->hid_dev_state), hidp->hid_internal_flag, 2179 hidp->hid_external_flag, (void *)hidp->hid_interrupt_pipe); 2180 2181 if (HID_IS_OPEN(hidp) && (hidp->hid_interrupt_pipe != NULL)) { 2182 /* 2183 * initialize interrupt pipe request structure 2184 */ 2185 req = usb_alloc_intr_req(hidp->hid_dip, 0, USB_FLAGS_SLEEP); 2186 req->intr_client_private = (usb_opaque_t)hidp; 2187 req->intr_attributes = USB_ATTRS_SHORT_XFER_OK | 2188 USB_ATTRS_AUTOCLEARING; 2189 req->intr_len = hidp->hid_packet_size; 2190 req->intr_cb = hid_interrupt_pipe_callback; 2191 req->intr_exc_cb = hid_interrupt_pipe_exception_callback; 2192 2193 /* 2194 * Start polling on the interrupt pipe. 2195 */ 2196 mutex_exit(&hidp->hid_mutex); 2197 2198 if ((rval = usb_pipe_intr_xfer(hidp->hid_interrupt_pipe, req, 2199 USB_FLAGS_SLEEP)) != USB_SUCCESS) { 2200 USB_DPRINTF_L2(PRINT_MASK_PM, hidp->hid_log_handle, 2201 "hid_start_intr_polling failed: rval = %d", 2202 rval); 2203 usb_free_intr_req(req); 2204 } 2205 2206 mutex_enter(&hidp->hid_mutex); 2207 } 2208 2209 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2210 "hid_start_intr_polling: done, rval = %d", rval); 2211 2212 return (rval); 2213 } 2214 2215 2216 /* 2217 * hid_close_intr_pipe: 2218 * close the interrupt pipe after draining all callbacks 2219 */ 2220 static void 2221 hid_close_intr_pipe(hid_state_t *hidp) 2222 { 2223 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 2224 "hid_close_intr_pipe: Begin"); 2225 2226 if (hidp->hid_interrupt_pipe) { 2227 /* 2228 * Close the interrupt pipe 2229 */ 2230 mutex_exit(&hidp->hid_mutex); 2231 usb_pipe_close(hidp->hid_dip, hidp->hid_interrupt_pipe, 2232 USB_FLAGS_SLEEP, NULL, NULL); 2233 mutex_enter(&hidp->hid_mutex); 2234 hidp->hid_interrupt_pipe = NULL; 2235 } 2236 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 2237 "hid_close_intr_pipe: End"); 2238 } 2239 2240 2241 /* 2242 * hid_mctl_receive: 2243 * Handle M_CTL messages from upper stream. If 2244 * we don't understand the command, free message. 2245 */ 2246 static int 2247 hid_mctl_receive(register queue_t *q, register mblk_t *mp) 2248 { 2249 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 2250 struct iocblk *iocp; 2251 int error = HID_FAILURE; 2252 uchar_t request_type; 2253 hid_req_t *hid_req_data = NULL; 2254 hid_polled_input_callback_t hid_polled_input; 2255 hid_vid_pid_t hid_vid_pid; 2256 2257 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2258 "hid_mctl_receive"); 2259 2260 iocp = (struct iocblk *)mp->b_rptr; 2261 2262 switch (iocp->ioc_cmd) { 2263 case HID_SET_REPORT: 2264 /* FALLTHRU */ 2265 case HID_SET_IDLE: 2266 /* FALLTHRU */ 2267 case HID_SET_PROTOCOL: 2268 request_type = USB_DEV_REQ_HOST_TO_DEV | 2269 USB_DEV_REQ_RCPT_IF | USB_DEV_REQ_TYPE_CLASS; 2270 2271 break; 2272 case HID_GET_REPORT: 2273 /* FALLTHRU */ 2274 case HID_GET_IDLE: 2275 /* FALLTHRU */ 2276 case HID_GET_PROTOCOL: 2277 request_type = USB_DEV_REQ_DEV_TO_HOST | 2278 USB_DEV_REQ_RCPT_IF | USB_DEV_REQ_TYPE_CLASS; 2279 2280 break; 2281 case HID_GET_PARSER_HANDLE: 2282 if (canputnext(RD(q))) { 2283 freemsg(mp->b_cont); 2284 mp->b_cont = hid_data2mblk( 2285 (uchar_t *)&hidp->hid_report_descr, 2286 sizeof (hidp->hid_report_descr)); 2287 if (mp->b_cont == NULL) { 2288 /* 2289 * can't allocate mblk, indicate 2290 * that nothing is returned 2291 */ 2292 iocp->ioc_count = 0; 2293 } else { 2294 iocp->ioc_count = 2295 sizeof (hidp->hid_report_descr); 2296 } 2297 qreply(q, mp); 2298 2299 return (HID_SUCCESS); 2300 } else { 2301 2302 /* retry */ 2303 return (HID_ENQUEUE); 2304 } 2305 case HID_GET_VID_PID: 2306 if (canputnext(RD(q))) { 2307 freemsg(mp->b_cont); 2308 2309 hid_vid_pid.VendorId = 2310 hidp->hid_dev_descr->idVendor; 2311 hid_vid_pid.ProductId = 2312 hidp->hid_dev_descr->idProduct; 2313 2314 mp->b_cont = hid_data2mblk( 2315 (uchar_t *)&hid_vid_pid, sizeof (hid_vid_pid_t)); 2316 if (mp->b_cont == NULL) { 2317 /* 2318 * can't allocate mblk, indicate that nothing 2319 * is being returned. 2320 */ 2321 iocp->ioc_count = 0; 2322 } else { 2323 iocp->ioc_count = 2324 sizeof (hid_vid_pid_t); 2325 } 2326 qreply(q, mp); 2327 2328 return (HID_SUCCESS); 2329 } else { 2330 2331 /* retry */ 2332 return (HID_ENQUEUE); 2333 } 2334 case HID_OPEN_POLLED_INPUT: 2335 if (canputnext(RD(q))) { 2336 freemsg(mp->b_cont); 2337 2338 /* Initialize the structure */ 2339 hid_polled_input.hid_polled_version = 2340 HID_POLLED_INPUT_V0; 2341 hid_polled_input.hid_polled_read = hid_polled_read; 2342 hid_polled_input.hid_polled_input_enter = 2343 hid_polled_input_enter; 2344 hid_polled_input.hid_polled_input_exit = 2345 hid_polled_input_exit; 2346 hid_polled_input.hid_polled_input_handle = 2347 (hid_polled_handle_t)hidp; 2348 2349 mp->b_cont = hid_data2mblk( 2350 (uchar_t *)&hid_polled_input, 2351 sizeof (hid_polled_input_callback_t)); 2352 if (mp->b_cont == NULL) { 2353 /* 2354 * can't allocate mblk, indicate that nothing 2355 * is being returned. 2356 */ 2357 iocp->ioc_count = 0; 2358 } else { 2359 /* Call down into USBA */ 2360 (void) hid_polled_input_init(hidp); 2361 2362 iocp->ioc_count = 2363 sizeof (hid_polled_input_callback_t); 2364 } 2365 qreply(q, mp); 2366 2367 return (HID_SUCCESS); 2368 } else { 2369 2370 /* retry */ 2371 return (HID_ENQUEUE); 2372 } 2373 case HID_CLOSE_POLLED_INPUT: 2374 /* Call down into USBA */ 2375 (void) hid_polled_input_fini(hidp); 2376 2377 iocp->ioc_count = 0; 2378 qreply(q, mp); 2379 2380 return (HID_SUCCESS); 2381 default: 2382 hid_qreply_merror(q, mp, EINVAL); 2383 2384 return (HID_FAILURE); 2385 } 2386 2387 /* 2388 * These (device executable) commands require a hid_req_t. 2389 * Make sure one is present 2390 */ 2391 if (mp->b_cont == NULL) { 2392 hid_qreply_merror(q, mp, EINVAL); 2393 2394 return (error); 2395 } else { 2396 hid_req_data = (hid_req_t *)mp->b_cont->b_rptr; 2397 if ((iocp->ioc_cmd == HID_SET_REPORT) && 2398 (hid_req_data->hid_req_wLength == 0)) { 2399 hid_qreply_merror(q, mp, EINVAL); 2400 2401 return (error); 2402 } 2403 } 2404 2405 /* 2406 * Check is version no. is correct. This 2407 * is coming from the user 2408 */ 2409 if (hid_req_data->hid_req_version_no != HID_VERSION_V_0) { 2410 hid_qreply_merror(q, mp, EINVAL); 2411 2412 return (error); 2413 } 2414 2415 mutex_enter(&hidp->hid_mutex); 2416 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2417 "hid_mctl_receive: dev_state=%s", 2418 usb_str_dev_state(hidp->hid_dev_state)); 2419 2420 switch (hidp->hid_dev_state) { 2421 case USB_DEV_PWRED_DOWN: 2422 /* 2423 * get the device full powered. We get a callback 2424 * which enables the WQ and kicks off IO 2425 */ 2426 hidp->hid_dev_state = USB_DEV_HID_POWER_CHANGE; 2427 mutex_exit(&hidp->hid_mutex); 2428 if (usb_req_raise_power(hidp->hid_dip, 0, 2429 USB_DEV_OS_FULL_PWR, hid_power_change_callback, 2430 hidp, 0) != USB_SUCCESS) { 2431 /* we retry raising power in wsrv */ 2432 mutex_enter(&hidp->hid_mutex); 2433 hidp->hid_dev_state = USB_DEV_PWRED_DOWN; 2434 mutex_exit(&hidp->hid_mutex); 2435 } 2436 error = HID_ENQUEUE; 2437 2438 break; 2439 case USB_DEV_HID_POWER_CHANGE: 2440 mutex_exit(&hidp->hid_mutex); 2441 error = HID_ENQUEUE; 2442 2443 break; 2444 case USB_DEV_ONLINE: 2445 if (HID_STREAMS_FLAG(q, hidp) != HID_STREAMS_DISMANTLING) { 2446 /* Send a message down */ 2447 mutex_exit(&hidp->hid_mutex); 2448 error = hid_mctl_execute_cmd(q, request_type, 2449 hid_req_data, mp); 2450 if (error == HID_FAILURE) { 2451 hid_qreply_merror(q, mp, EIO); 2452 } 2453 } else { 2454 mutex_exit(&hidp->hid_mutex); 2455 hid_qreply_merror(q, mp, EIO); 2456 } 2457 2458 break; 2459 default: 2460 mutex_exit(&hidp->hid_mutex); 2461 hid_qreply_merror(q, mp, EIO); 2462 2463 break; 2464 } 2465 2466 return (error); 2467 } 2468 2469 2470 /* 2471 * hid_mctl_execute_cmd: 2472 * Send the command to the device. 2473 */ 2474 static int 2475 hid_mctl_execute_cmd(queue_t *q, int request_type, hid_req_t *hid_req_data, 2476 mblk_t *mp) 2477 { 2478 int request_index; 2479 struct iocblk *iocp; 2480 hid_default_pipe_arg_t *def_pipe_arg; 2481 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 2482 2483 iocp = (struct iocblk *)mp->b_rptr; 2484 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2485 "hid_mctl_execute_cmd: iocp=0x%p", (void *)iocp); 2486 2487 request_index = hidp->hid_if_descr.bInterfaceNumber; 2488 2489 /* 2490 * Set up the argument to be passed back to hid 2491 * when the asynchronous control callback is 2492 * executed. 2493 */ 2494 def_pipe_arg = kmem_zalloc(sizeof (hid_default_pipe_arg_t), 0); 2495 2496 if (def_pipe_arg == NULL) { 2497 2498 return (HID_FAILURE); 2499 } 2500 2501 def_pipe_arg->hid_default_pipe_arg_queue = q; 2502 def_pipe_arg->hid_default_pipe_arg_mctlmsg.ioc_cmd = iocp->ioc_cmd; 2503 def_pipe_arg->hid_default_pipe_arg_mctlmsg.ioc_count = 0; 2504 def_pipe_arg->hid_default_pipe_arg_mblk = mp; 2505 2506 /* 2507 * Send the command down to USBA through default 2508 * pipe. 2509 */ 2510 if (hid_send_async_ctrl_request(def_pipe_arg, hid_req_data, 2511 request_type, iocp->ioc_cmd, request_index) != USB_SUCCESS) { 2512 2513 kmem_free(def_pipe_arg, sizeof (hid_default_pipe_arg_t)); 2514 2515 return (HID_FAILURE); 2516 } 2517 2518 return (HID_INPROGRESS); 2519 } 2520 2521 2522 /* 2523 * hid_send_async_ctrl_request: 2524 * Send an asynchronous control request to USBA. Since hid is a STREAMS 2525 * driver, it is not allowed to wait in its entry points except for the 2526 * open and close entry points. Therefore, hid must use the asynchronous 2527 * USBA calls. 2528 */ 2529 static int 2530 hid_send_async_ctrl_request(hid_default_pipe_arg_t *hid_default_pipe_arg, 2531 hid_req_t *hid_request, uchar_t request_type, int request_request, 2532 ushort_t request_index) 2533 { 2534 queue_t *q = hid_default_pipe_arg->hid_default_pipe_arg_queue; 2535 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 2536 usb_ctrl_req_t *ctrl_req; 2537 int rval; 2538 size_t length = 0; 2539 2540 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2541 "hid_send_async_ctrl_request: " 2542 "rq_type=%d rq_rq=%d index=%d", 2543 request_type, request_request, request_index); 2544 2545 mutex_enter(&hidp->hid_mutex); 2546 hidp->hid_default_pipe_req++; 2547 mutex_exit(&hidp->hid_mutex); 2548 2549 /* 2550 * Note that ctrl_req->ctrl_data should be allocated by usba 2551 * only for IN requests. OUT request(e.g SET_REPORT) can have a 2552 * non-zero wLength value but ctrl_data would be allocated by 2553 * client for them. 2554 */ 2555 if (hid_request->hid_req_wLength >= MAX_REPORT_DATA) { 2556 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 2557 "hid_req_wLength is exceeded"); 2558 return (USB_FAILURE); 2559 } 2560 if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_DEV_TO_HOST) { 2561 length = hid_request->hid_req_wLength; 2562 } 2563 2564 if ((ctrl_req = usb_alloc_ctrl_req(hidp->hid_dip, length, 0)) == NULL) { 2565 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 2566 "unable to alloc ctrl req. async trans failed"); 2567 mutex_enter(&hidp->hid_mutex); 2568 hidp->hid_default_pipe_req--; 2569 ASSERT(hidp->hid_default_pipe_req >= 0); 2570 mutex_exit(&hidp->hid_mutex); 2571 2572 return (USB_FAILURE); 2573 } 2574 2575 if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_HOST_TO_DEV) { 2576 ASSERT((length == 0) && (ctrl_req->ctrl_data == NULL)); 2577 } 2578 2579 ctrl_req->ctrl_bmRequestType = request_type; 2580 ctrl_req->ctrl_bRequest = (uint8_t)request_request; 2581 ctrl_req->ctrl_wValue = hid_request->hid_req_wValue; 2582 ctrl_req->ctrl_wIndex = request_index; 2583 ctrl_req->ctrl_wLength = hid_request->hid_req_wLength; 2584 /* host to device: create a msg from hid_req_data */ 2585 if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_HOST_TO_DEV) { 2586 mblk_t *pblk = allocb(hid_request->hid_req_wLength, BPRI_HI); 2587 if (pblk == NULL) { 2588 usb_free_ctrl_req(ctrl_req); 2589 return (USB_FAILURE); 2590 } 2591 bcopy(hid_request->hid_req_data, pblk->b_wptr, 2592 hid_request->hid_req_wLength); 2593 pblk->b_wptr += hid_request->hid_req_wLength; 2594 ctrl_req->ctrl_data = pblk; 2595 } 2596 ctrl_req->ctrl_attributes = USB_ATTRS_AUTOCLEARING; 2597 ctrl_req->ctrl_client_private = (usb_opaque_t)hid_default_pipe_arg; 2598 ctrl_req->ctrl_cb = hid_default_pipe_callback; 2599 ctrl_req->ctrl_exc_cb = hid_default_pipe_exception_callback; 2600 2601 if ((rval = usb_pipe_ctrl_xfer(hidp->hid_default_pipe, 2602 ctrl_req, 0)) != USB_SUCCESS) { 2603 mutex_enter(&hidp->hid_mutex); 2604 hidp->hid_default_pipe_req--; 2605 ASSERT(hidp->hid_default_pipe_req >= 0); 2606 mutex_exit(&hidp->hid_mutex); 2607 2608 usb_free_ctrl_req(ctrl_req); 2609 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 2610 "usb_pipe_ctrl_xfer() failed. rval = %d", rval); 2611 2612 return (USB_FAILURE); 2613 } 2614 2615 return (USB_SUCCESS); 2616 } 2617 2618 /* 2619 * hid_create_pm_components: 2620 * Create the pm components required for power management. 2621 * For keyboard/mouse, the components is created only if the device 2622 * supports a remote wakeup. 2623 * For other hid devices they are created unconditionally. 2624 */ 2625 static void 2626 hid_create_pm_components(dev_info_t *dip, hid_state_t *hidp) 2627 { 2628 hid_power_t *hidpm; 2629 uint_t pwr_states; 2630 2631 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2632 "hid_create_pm_components: Begin"); 2633 2634 /* Allocate the state structure */ 2635 hidpm = kmem_zalloc(sizeof (hid_power_t), KM_SLEEP); 2636 hidp->hid_pm = hidpm; 2637 hidpm->hid_state = hidp; 2638 hidpm->hid_raise_power = B_FALSE; 2639 hidpm->hid_pm_capabilities = 0; 2640 hidpm->hid_current_power = USB_DEV_OS_FULL_PWR; 2641 2642 switch (hidp->hid_if_descr.bInterfaceProtocol) { 2643 case KEYBOARD_PROTOCOL: 2644 case MOUSE_PROTOCOL: 2645 hidpm->hid_pm_strategy = HID_PM_ACTIVITY; 2646 if ((hid_is_pm_enabled(dip) == USB_SUCCESS) && 2647 (usb_handle_remote_wakeup(dip, USB_REMOTE_WAKEUP_ENABLE) == 2648 USB_SUCCESS)) { 2649 2650 USB_DPRINTF_L3(PRINT_MASK_PM, hidp->hid_log_handle, 2651 "hid_create_pm_components: Remote Wakeup Enabled"); 2652 2653 if (usb_create_pm_components(dip, &pwr_states) == 2654 USB_SUCCESS) { 2655 hidpm->hid_wakeup_enabled = 1; 2656 hidpm->hid_pwr_states = (uint8_t)pwr_states; 2657 } 2658 } 2659 2660 break; 2661 default: 2662 hidpm->hid_pm_strategy = HID_PM_OPEN_CLOSE; 2663 if ((hid_is_pm_enabled(dip) == USB_SUCCESS) && 2664 (usb_create_pm_components(dip, &pwr_states) == 2665 USB_SUCCESS)) { 2666 hidpm->hid_wakeup_enabled = 0; 2667 hidpm->hid_pwr_states = (uint8_t)pwr_states; 2668 } 2669 2670 break; 2671 } 2672 2673 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2674 "hid_create_pm_components: END"); 2675 } 2676 2677 2678 /* 2679 * hid_is_pm_enabled 2680 * Check if the device is pm enabled. Always enable 2681 * pm on the new SUN mouse 2682 */ 2683 static int 2684 hid_is_pm_enabled(dev_info_t *dip) 2685 { 2686 hid_state_t *hidp = ddi_get_soft_state(hid_statep, 2687 ddi_get_instance(dip)); 2688 2689 if (strcmp(ddi_node_name(dip), "mouse") == 0) { 2690 /* check for overrides first */ 2691 if (hid_pm_mouse || 2692 (ddi_prop_exists(DDI_DEV_T_ANY, dip, 2693 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 2694 "hid-mouse-pm-enable") == 1)) { 2695 2696 return (USB_SUCCESS); 2697 } 2698 2699 /* 2700 * Always enable PM for 1.05 or greater SUN mouse 2701 * hidp->hid_dev_descr won't be NULL. 2702 */ 2703 if ((hidp->hid_dev_descr->idVendor == 2704 HID_SUN_MOUSE_VENDOR_ID) && 2705 (hidp->hid_dev_descr->idProduct == 2706 HID_SUN_MOUSE_PROD_ID) && 2707 (hidp->hid_dev_descr->bcdDevice >= 2708 HID_SUN_MOUSE_BCDDEVICE)) { 2709 2710 return (USB_SUCCESS); 2711 } 2712 } else { 2713 2714 return (USB_SUCCESS); 2715 } 2716 2717 return (USB_FAILURE); 2718 } 2719 2720 2721 /* 2722 * hid_save_device_state 2723 * Save the current device/driver state. 2724 */ 2725 static void 2726 hid_save_device_state(hid_state_t *hidp) 2727 { 2728 struct iocblk *mctlmsg; 2729 mblk_t *mp; 2730 queue_t *q; 2731 2732 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 2733 "hid_save_device_state"); 2734 2735 if (!(HID_IS_OPEN(hidp))) 2736 return; 2737 2738 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) { 2739 /* 2740 * Send MCTLs up indicating that the device 2741 * will loose its state 2742 */ 2743 q = hidp->hid_internal_rq; 2744 2745 mutex_exit(&hidp->hid_mutex); 2746 if (canputnext(q)) { 2747 mp = allocb(sizeof (struct iocblk), BPRI_HI); 2748 if (mp != NULL) { 2749 mp->b_datap->db_type = M_CTL; 2750 mctlmsg = (struct iocblk *) 2751 mp->b_datap->db_base; 2752 mctlmsg->ioc_cmd = HID_DISCONNECT_EVENT; 2753 mctlmsg->ioc_count = 0; 2754 putnext(q, mp); 2755 } 2756 } 2757 mutex_enter(&hidp->hid_mutex); 2758 } 2759 2760 if (hidp->hid_external_flag == HID_STREAMS_OPEN) { 2761 /* 2762 * Send MCTLs up indicating that the device 2763 * will loose its state 2764 */ 2765 q = hidp->hid_external_rq; 2766 2767 mutex_exit(&hidp->hid_mutex); 2768 if (canputnext(q)) { 2769 mp = allocb(sizeof (struct iocblk), BPRI_HI); 2770 if (mp != NULL) { 2771 mp->b_datap->db_type = M_CTL; 2772 mctlmsg = (struct iocblk *) 2773 mp->b_datap->db_base; 2774 mctlmsg->ioc_cmd = HID_DISCONNECT_EVENT; 2775 mctlmsg->ioc_count = 0; 2776 putnext(q, mp); 2777 } 2778 } 2779 mutex_enter(&hidp->hid_mutex); 2780 } 2781 2782 mutex_exit(&hidp->hid_mutex); 2783 /* stop polling on the intr pipe */ 2784 usb_pipe_stop_intr_polling(hidp->hid_interrupt_pipe, USB_FLAGS_SLEEP); 2785 mutex_enter(&hidp->hid_mutex); 2786 } 2787 2788 2789 /* 2790 * hid_restore_device_state: 2791 * Set original configuration of the device. 2792 * Reopen intr pipe. 2793 * Enable wrq - this starts new transactions on the control pipe. 2794 */ 2795 static void 2796 hid_restore_device_state(dev_info_t *dip, hid_state_t *hidp) 2797 { 2798 int rval; 2799 hid_power_t *hidpm; 2800 struct iocblk *mctlmsg; 2801 mblk_t *mp; 2802 queue_t *q; 2803 2804 hid_pm_busy_component(hidp); 2805 mutex_enter(&hidp->hid_mutex); 2806 2807 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2808 "hid_restore_device_state: %s", 2809 usb_str_dev_state(hidp->hid_dev_state)); 2810 2811 hidpm = hidp->hid_pm; 2812 mutex_exit(&hidp->hid_mutex); 2813 2814 /* First bring the device to full power */ 2815 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 2816 2817 mutex_enter(&hidp->hid_mutex); 2818 if (hidp->hid_dev_state == USB_DEV_ONLINE) { 2819 /* 2820 * We failed the checkpoint, there is no need to restore 2821 * the device state 2822 */ 2823 mutex_exit(&hidp->hid_mutex); 2824 hid_pm_idle_component(hidp); 2825 2826 return; 2827 } 2828 mutex_exit(&hidp->hid_mutex); 2829 2830 2831 /* Check if we are talking to the same device */ 2832 if (usb_check_same_device(dip, hidp->hid_log_handle, USB_LOG_L2, 2833 PRINT_MASK_ALL, USB_CHK_BASIC|USB_CHK_CFG, NULL) != USB_SUCCESS) { 2834 2835 /* change the device state from suspended to disconnected */ 2836 mutex_enter(&hidp->hid_mutex); 2837 hidp->hid_dev_state = USB_DEV_DISCONNECTED; 2838 mutex_exit(&hidp->hid_mutex); 2839 hid_pm_idle_component(hidp); 2840 goto nodev; 2841 } 2842 2843 hid_set_idle(hidp); 2844 hid_set_protocol(hidp, SET_REPORT_PROTOCOL); 2845 2846 mutex_enter(&hidp->hid_mutex); 2847 /* if the device had remote wakeup earlier, enable it again */ 2848 if (hidpm->hid_wakeup_enabled) { 2849 mutex_exit(&hidp->hid_mutex); 2850 2851 if ((rval = usb_handle_remote_wakeup(hidp->hid_dip, 2852 USB_REMOTE_WAKEUP_ENABLE)) != USB_SUCCESS) { 2853 USB_DPRINTF_L2(PRINT_MASK_ATTA, 2854 hidp->hid_log_handle, 2855 "usb_handle_remote_wakeup failed (%d)", rval); 2856 } 2857 2858 mutex_enter(&hidp->hid_mutex); 2859 } 2860 2861 /* 2862 * restart polling on the interrupt pipe only if the device 2863 * was previously operational (open) 2864 */ 2865 if (HID_IS_OPEN(hidp)) { 2866 if ((rval = hid_start_intr_polling(hidp)) != USB_SUCCESS) { 2867 USB_DPRINTF_L3(PRINT_MASK_ATTA, hidp->hid_log_handle, 2868 "hid_restore_device_state:" 2869 "unable to restart intr pipe poll" 2870 " rval = %d ", rval); 2871 /* 2872 * change the device state from 2873 * suspended to disconnected 2874 */ 2875 hidp->hid_dev_state = USB_DEV_DISCONNECTED; 2876 mutex_exit(&hidp->hid_mutex); 2877 hid_pm_idle_component(hidp); 2878 goto nodev; 2879 } 2880 2881 if (hidp->hid_dev_state == USB_DEV_DISCONNECTED) { 2882 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 2883 "device is being re-connected"); 2884 } 2885 2886 /* set the device state ONLINE */ 2887 hidp->hid_dev_state = USB_DEV_ONLINE; 2888 2889 /* inform upstream modules that the device is back */ 2890 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) { 2891 q = hidp->hid_internal_rq; 2892 2893 mutex_exit(&hidp->hid_mutex); 2894 if (canputnext(q)) { 2895 mp = allocb(sizeof (struct iocblk), BPRI_HI); 2896 if (mp != NULL) { 2897 mp->b_datap->db_type = M_CTL; 2898 mctlmsg = (struct iocblk *) 2899 mp->b_datap->db_base; 2900 mctlmsg->ioc_cmd = HID_CONNECT_EVENT; 2901 mctlmsg->ioc_count = 0; 2902 putnext(q, mp); 2903 } 2904 } 2905 /* enable write side q */ 2906 qenable(WR(q)); 2907 mutex_enter(&hidp->hid_mutex); 2908 } 2909 2910 if (hidp->hid_external_flag == HID_STREAMS_OPEN) { 2911 q = hidp->hid_external_rq; 2912 2913 mutex_exit(&hidp->hid_mutex); 2914 if (canputnext(q)) { 2915 mp = allocb(sizeof (struct iocblk), BPRI_HI); 2916 if (mp != NULL) { 2917 mp->b_datap->db_type = M_CTL; 2918 mctlmsg = (struct iocblk *) 2919 mp->b_datap->db_base; 2920 mctlmsg->ioc_cmd = HID_CONNECT_EVENT; 2921 mctlmsg->ioc_count = 0; 2922 putnext(q, mp); 2923 } 2924 } 2925 /* enable write side q */ 2926 qenable(WR(q)); 2927 mutex_enter(&hidp->hid_mutex); 2928 } 2929 } else { 2930 /* set the device state ONLINE */ 2931 hidp->hid_dev_state = USB_DEV_ONLINE; 2932 } 2933 2934 mutex_exit(&hidp->hid_mutex); 2935 hid_pm_idle_component(hidp); 2936 return; 2937 2938 nodev: 2939 /* 2940 * Notify applications about device removal. This only 2941 * applies to an external (aka. physical) open. Not sure how to 2942 * notify consconfig to close the internal minor node. 2943 */ 2944 mutex_enter(&hidp->hid_mutex); 2945 2946 if ((q = hidp->hid_external_rq) == NULL) { 2947 mutex_exit(&hidp->hid_mutex); 2948 return; 2949 } 2950 2951 mutex_exit(&hidp->hid_mutex); 2952 mp = allocb(sizeof (uchar_t), BPRI_HI); 2953 if (mp != NULL) { 2954 mp->b_datap->db_type = M_ERROR; 2955 mp->b_rptr = mp->b_datap->db_base; 2956 mp->b_wptr = mp->b_rptr + sizeof (char); 2957 *mp->b_rptr = ENODEV; 2958 putnext(q, mp); 2959 } 2960 } 2961 2962 2963 /* 2964 * hid_qreply_merror: 2965 * Pass an error message up. 2966 */ 2967 static void 2968 hid_qreply_merror(queue_t *q, mblk_t *mp, uchar_t errval) 2969 { 2970 mp->b_datap->db_type = M_ERROR; 2971 if (mp->b_cont) { 2972 freemsg(mp->b_cont); 2973 mp->b_cont = NULL; 2974 } 2975 mp->b_rptr = mp->b_datap->db_base; 2976 mp->b_wptr = mp->b_rptr + sizeof (char); 2977 *mp->b_rptr = errval; 2978 2979 qreply(q, mp); 2980 } 2981 2982 2983 /* 2984 * hid_data2mblk: 2985 * Form an mblk from the given data 2986 */ 2987 static mblk_t * 2988 hid_data2mblk(uchar_t *buf, int len) 2989 { 2990 mblk_t *mp = NULL; 2991 2992 if (len >= 0) { 2993 mp = allocb(len, BPRI_HI); 2994 if (mp) { 2995 bcopy(buf, mp->b_datap->db_base, len); 2996 mp->b_wptr += len; 2997 } 2998 } 2999 3000 return (mp); 3001 } 3002 3003 3004 /* 3005 * hid_flush : 3006 * Flush data already sent upstreams to client module. 3007 */ 3008 static void 3009 hid_flush(queue_t *q) 3010 { 3011 /* 3012 * Flush pending data already sent upstream 3013 */ 3014 if ((q != NULL) && (q->q_next != NULL)) { 3015 (void) putnextctl1(q, M_FLUSH, FLUSHR); 3016 } 3017 } 3018 3019 3020 static void 3021 hid_pm_busy_component(hid_state_t *hid_statep) 3022 { 3023 ASSERT(!mutex_owned(&hid_statep->hid_mutex)); 3024 3025 if (hid_statep->hid_pm != NULL) { 3026 mutex_enter(&hid_statep->hid_mutex); 3027 hid_statep->hid_pm->hid_pm_busy++; 3028 3029 USB_DPRINTF_L4(PRINT_MASK_PM, hid_statep->hid_log_handle, 3030 "hid_pm_busy_component: %d", 3031 hid_statep->hid_pm->hid_pm_busy); 3032 3033 mutex_exit(&hid_statep->hid_mutex); 3034 if (pm_busy_component(hid_statep->hid_dip, 0) != DDI_SUCCESS) { 3035 mutex_enter(&hid_statep->hid_mutex); 3036 hid_statep->hid_pm->hid_pm_busy--; 3037 3038 USB_DPRINTF_L2(PRINT_MASK_PM, 3039 hid_statep->hid_log_handle, 3040 "hid_pm_busy_component failed: %d", 3041 hid_statep->hid_pm->hid_pm_busy); 3042 3043 mutex_exit(&hid_statep->hid_mutex); 3044 } 3045 3046 } 3047 } 3048 3049 3050 static void 3051 hid_pm_idle_component(hid_state_t *hid_statep) 3052 { 3053 ASSERT(!mutex_owned(&hid_statep->hid_mutex)); 3054 3055 if (hid_statep->hid_pm != NULL) { 3056 if (pm_idle_component(hid_statep->hid_dip, 0) == DDI_SUCCESS) { 3057 mutex_enter(&hid_statep->hid_mutex); 3058 ASSERT(hid_statep->hid_pm->hid_pm_busy > 0); 3059 hid_statep->hid_pm->hid_pm_busy--; 3060 3061 USB_DPRINTF_L4(PRINT_MASK_PM, 3062 hid_statep->hid_log_handle, 3063 "hid_pm_idle_component: %d", 3064 hid_statep->hid_pm->hid_pm_busy); 3065 3066 mutex_exit(&hid_statep->hid_mutex); 3067 } 3068 } 3069 } 3070 3071 3072 /* 3073 * hid_pwrlvl0: 3074 * Functions to handle power transition for various levels 3075 * These functions act as place holders to issue USB commands 3076 * to the devices to change their power levels 3077 */ 3078 static int 3079 hid_pwrlvl0(hid_state_t *hidp) 3080 { 3081 hid_power_t *hidpm; 3082 int rval; 3083 struct iocblk *mctlmsg; 3084 mblk_t *mp_lowpwr, *mp_fullpwr; 3085 queue_t *q; 3086 3087 hidpm = hidp->hid_pm; 3088 3089 switch (hidp->hid_dev_state) { 3090 case USB_DEV_ONLINE: 3091 /* Deny the powerdown request if the device is busy */ 3092 if (hidpm->hid_pm_busy != 0) { 3093 3094 return (USB_FAILURE); 3095 } 3096 3097 if (HID_IS_OPEN(hidp)) { 3098 q = hidp->hid_inuse_rq; 3099 mutex_exit(&hidp->hid_mutex); 3100 if (canputnext(q)) { 3101 /* try to preallocate mblks */ 3102 mp_lowpwr = allocb( 3103 (int)sizeof (struct iocblk), BPRI_HI); 3104 mp_fullpwr = allocb( 3105 (int)sizeof (struct iocblk), BPRI_HI); 3106 if ((mp_lowpwr != NULL) && 3107 (mp_fullpwr != NULL)) { 3108 /* stop polling */ 3109 usb_pipe_stop_intr_polling( 3110 hidp->hid_interrupt_pipe, 3111 USB_FLAGS_SLEEP); 3112 3113 /* 3114 * Send an MCTL up indicating that 3115 * we are powering off 3116 */ 3117 mp_lowpwr->b_datap->db_type = M_CTL; 3118 mctlmsg = (struct iocblk *) 3119 mp_lowpwr->b_datap->db_base; 3120 mctlmsg->ioc_cmd = HID_POWER_OFF; 3121 mctlmsg->ioc_count = 0; 3122 putnext(q, mp_lowpwr); 3123 3124 /* save the full powr mblk */ 3125 mutex_enter(&hidp->hid_mutex); 3126 hidpm->hid_pm_pwrup = mp_fullpwr; 3127 } else { 3128 /* 3129 * Since we failed to allocate one 3130 * or more mblks, we fail attempt 3131 * to go into low power this time 3132 */ 3133 freemsg(mp_lowpwr); 3134 freemsg(mp_fullpwr); 3135 mutex_enter(&hidp->hid_mutex); 3136 3137 return (USB_FAILURE); 3138 } 3139 } else { 3140 /* 3141 * Since we can't send an mblk up, 3142 * we fail this attempt to go to low power 3143 */ 3144 mutex_enter(&hidp->hid_mutex); 3145 3146 return (USB_FAILURE); 3147 } 3148 } 3149 3150 mutex_exit(&hidp->hid_mutex); 3151 /* Issue USB D3 command to the device here */ 3152 rval = usb_set_device_pwrlvl3(hidp->hid_dip); 3153 ASSERT(rval == USB_SUCCESS); 3154 3155 mutex_enter(&hidp->hid_mutex); 3156 hidp->hid_dev_state = USB_DEV_PWRED_DOWN; 3157 hidpm->hid_current_power = USB_DEV_OS_PWR_OFF; 3158 3159 /* FALLTHRU */ 3160 case USB_DEV_DISCONNECTED: 3161 case USB_DEV_SUSPENDED: 3162 case USB_DEV_PWRED_DOWN: 3163 default: 3164 break; 3165 } 3166 3167 return (USB_SUCCESS); 3168 } 3169 3170 3171 /* ARGSUSED */ 3172 static int 3173 hid_pwrlvl1(hid_state_t *hidp) 3174 { 3175 int rval; 3176 3177 /* Issue USB D2 command to the device here */ 3178 rval = usb_set_device_pwrlvl2(hidp->hid_dip); 3179 ASSERT(rval == USB_SUCCESS); 3180 3181 return (USB_FAILURE); 3182 } 3183 3184 3185 /* ARGSUSED */ 3186 static int 3187 hid_pwrlvl2(hid_state_t *hidp) 3188 { 3189 int rval; 3190 3191 rval = usb_set_device_pwrlvl1(hidp->hid_dip); 3192 ASSERT(rval == USB_SUCCESS); 3193 3194 return (USB_FAILURE); 3195 } 3196 3197 3198 static int 3199 hid_pwrlvl3(hid_state_t *hidp) 3200 { 3201 hid_power_t *hidpm; 3202 int rval; 3203 struct iocblk *mctlmsg; 3204 mblk_t *mp; 3205 queue_t *q; 3206 3207 hidpm = hidp->hid_pm; 3208 3209 switch (hidp->hid_dev_state) { 3210 case USB_DEV_HID_POWER_CHANGE: 3211 case USB_DEV_PWRED_DOWN: 3212 /* Issue USB D0 command to the device here */ 3213 rval = usb_set_device_pwrlvl0(hidp->hid_dip); 3214 ASSERT(rval == USB_SUCCESS); 3215 3216 if (HID_IS_OPEN(hidp)) { 3217 /* restart polling on intr pipe */ 3218 rval = hid_start_intr_polling(hidp); 3219 if (rval != USB_SUCCESS) { 3220 USB_DPRINTF_L2(PRINT_MASK_EVENTS, 3221 hidp->hid_log_handle, 3222 "unable to restart intr polling rval = %d", 3223 rval); 3224 3225 return (USB_FAILURE); 3226 } 3227 3228 /* Send an MCTL up indicating device in full power */ 3229 q = hidp->hid_inuse_rq; 3230 mp = hidpm->hid_pm_pwrup; 3231 hidpm->hid_pm_pwrup = NULL; 3232 mutex_exit(&hidp->hid_mutex); 3233 if (canputnext(q)) { 3234 mp->b_datap->db_type = M_CTL; 3235 mctlmsg = (struct iocblk *) 3236 mp->b_datap->db_base; 3237 mctlmsg->ioc_cmd = HID_FULL_POWER; 3238 mctlmsg->ioc_count = 0; 3239 putnext(q, mp); 3240 } else { 3241 freemsg(mp); 3242 } 3243 mutex_enter(&hidp->hid_mutex); 3244 } 3245 3246 hidp->hid_dev_state = USB_DEV_ONLINE; 3247 hidpm->hid_current_power = USB_DEV_OS_FULL_PWR; 3248 3249 /* FALLTHRU */ 3250 case USB_DEV_DISCONNECTED: 3251 case USB_DEV_SUSPENDED: 3252 case USB_DEV_ONLINE: 3253 3254 return (USB_SUCCESS); 3255 default: 3256 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 3257 "hid_pwrlvl3: Improper State"); 3258 3259 return (USB_FAILURE); 3260 } 3261 } 3262 3263 3264 /* 3265 * hid_polled_input_init : 3266 * This routine calls down to the lower layers to initialize any state 3267 * information. This routine initializes the lower layers for input. 3268 */ 3269 static int 3270 hid_polled_input_init(hid_state_t *hidp) 3271 { 3272 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 3273 "hid_polled_input_init"); 3274 3275 /* 3276 * Call the lower layers to intialize any state information 3277 * that they will need to provide the polled characters. 3278 */ 3279 if (usb_console_input_init(hidp->hid_dip, hidp->hid_interrupt_pipe, 3280 &hidp->hid_polled_raw_buf, 3281 &hidp->hid_polled_console_info) != USB_SUCCESS) { 3282 /* 3283 * If for some reason the lower layers cannot initialized, then 3284 * bail. 3285 */ 3286 (void) hid_polled_input_fini(hidp); 3287 3288 return (USB_FAILURE); 3289 } 3290 3291 return (USB_SUCCESS); 3292 } 3293 3294 3295 /* 3296 * hid_polled_input_fini: 3297 * This routine is called when we are done using this device as an input 3298 * device. 3299 */ 3300 static int 3301 hid_polled_input_fini(hid_state_t *hidp) 3302 { 3303 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 3304 "hid_polled_input_fini"); 3305 3306 /* 3307 * Call the lower layers to free any state information 3308 * only if polled input has been initialised. 3309 */ 3310 if ((hidp->hid_polled_console_info) && 3311 (usb_console_input_fini(hidp->hid_polled_console_info) != 3312 USB_SUCCESS)) { 3313 3314 return (USB_FAILURE); 3315 } 3316 hidp->hid_polled_console_info = NULL; 3317 3318 return (USB_SUCCESS); 3319 } 3320 3321 3322 /* 3323 * hid_polled_input_enter: 3324 * This is the routine that is called in polled mode to save the USB 3325 * state information before using the USB keyboard as an input device. 3326 * This routine, and all of the routines that it calls, are responsible 3327 * for saving any state information so that it can be restored when 3328 * polling mode is over. 3329 */ 3330 static int 3331 /* ARGSUSED */ 3332 hid_polled_input_enter(hid_polled_handle_t hid_polled_inputp) 3333 { 3334 hid_state_t *hidp = (hid_state_t *)hid_polled_inputp; 3335 3336 /* 3337 * Call the lower layers to tell them to save any state information. 3338 */ 3339 (void) usb_console_input_enter(hidp->hid_polled_console_info); 3340 3341 return (USB_SUCCESS); 3342 } 3343 3344 3345 /* 3346 * hid_polled_read : 3347 * This is the routine that is called in polled mode when it wants to read 3348 * a character. We will call to the lower layers to see if there is any 3349 * input data available. If there is USB scancodes available, we will 3350 * give them back. 3351 */ 3352 static int 3353 hid_polled_read(hid_polled_handle_t hid_polled_input, uchar_t **buffer) 3354 { 3355 hid_state_t *hidp = (hid_state_t *)hid_polled_input; 3356 uint_t num_bytes; 3357 3358 /* 3359 * Call the lower layers to get the character from the controller. 3360 * The lower layers will return the number of characters that 3361 * were put in the raw buffer. The address of the raw buffer 3362 * was passed down to the lower layers during hid_polled_init. 3363 */ 3364 if (usb_console_read(hidp->hid_polled_console_info, 3365 &num_bytes) != USB_SUCCESS) { 3366 3367 return (0); 3368 } 3369 3370 _NOTE(NO_COMPETING_THREADS_NOW); 3371 3372 *buffer = hidp->hid_polled_raw_buf; 3373 3374 _NOTE(COMPETING_THREADS_NOW); 3375 3376 /* 3377 * Return the number of characters that were copied into the 3378 * polled buffer. 3379 */ 3380 return (num_bytes); 3381 } 3382 3383 3384 /* 3385 * hid_polled_input_exit : 3386 * This is the routine that is called in polled mode when it is giving up 3387 * control of the USB keyboard. This routine, and the lower layer routines 3388 * that it calls, are responsible for restoring the controller state to the 3389 * state it was in before polled mode. 3390 */ 3391 static int 3392 hid_polled_input_exit(hid_polled_handle_t hid_polled_inputp) 3393 { 3394 hid_state_t *hidp = (hid_state_t *)hid_polled_inputp; 3395 3396 /* 3397 * Call the lower layers to restore any state information. 3398 */ 3399 (void) usb_console_input_exit(hidp->hid_polled_console_info); 3400 3401 return (0); 3402 } 3403