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