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 */ 25 26 27 /* 28 * Human Interface Device driver (HID) 29 * 30 * The HID driver is a software driver which acts as a class 31 * driver for USB human input devices like keyboard, mouse, 32 * joystick etc and provides the class-specific interfaces 33 * between these client driver modules and the Universal Serial 34 * Bus Driver(USBA). 35 * 36 * NOTE: This driver is not DDI compliant in that it uses undocumented 37 * functions for logging (USB_DPRINTF_L*, usb_alloc_log_hdl, usb_free_log_hdl). 38 * 39 * Undocumented functions may go away in a future Solaris OS release. 40 * 41 * Please see the DDK for sample code of these functions, and for the usbskel 42 * skeleton template driver which contains scaled-down versions of these 43 * functions written in a DDI-compliant way. 44 */ 45 46 #define USBDRV_MAJOR_VER 2 47 #define USBDRV_MINOR_VER 0 48 49 #include <sys/usb/usba.h> 50 #include <sys/usb/usba/genconsole.h> 51 #include <sys/usb/clients/hid/hid.h> 52 #include <sys/usb/clients/hid/hid_polled.h> 53 #include <sys/usb/clients/hidparser/hidparser.h> 54 #include <sys/usb/clients/hid/hidvar.h> 55 #include <sys/usb/clients/hid/hidminor.h> 56 #include <sys/usb/clients/hidparser/hid_parser_driver.h> 57 #include <sys/stropts.h> 58 #include <sys/sunddi.h> 59 #include <sys/stream.h> 60 #include <sys/strsun.h> 61 62 extern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t); 63 64 /* Debugging support */ 65 uint_t hid_errmask = (uint_t)PRINT_MASK_ALL; 66 uint_t hid_errlevel = USB_LOG_L4; 67 uint_t hid_instance_debug = (uint_t)-1; 68 69 /* tunables */ 70 int hid_default_pipe_drain_timeout = HID_DEFAULT_PIPE_DRAIN_TIMEOUT; 71 int hid_pm_mouse = 1; /* enable remote_wakeup for USB mouse/keyboard */ 72 73 /* soft state structures */ 74 #define HID_INITIAL_SOFT_SPACE 4 75 static void *hid_statep; 76 77 /* Callbacks */ 78 static void hid_interrupt_pipe_callback(usb_pipe_handle_t, 79 usb_intr_req_t *); 80 static void hid_default_pipe_callback(usb_pipe_handle_t, usb_ctrl_req_t *); 81 static void hid_interrupt_pipe_exception_callback(usb_pipe_handle_t, 82 usb_intr_req_t *); 83 static void hid_default_pipe_exception_callback(usb_pipe_handle_t, 84 usb_ctrl_req_t *); 85 static int hid_restore_state_event_callback(dev_info_t *); 86 static int hid_disconnect_event_callback(dev_info_t *); 87 static int hid_cpr_suspend(hid_state_t *hidp); 88 static void hid_cpr_resume(hid_state_t *hidp); 89 static void hid_power_change_callback(void *arg, int rval); 90 91 /* Supporting routines */ 92 static size_t hid_parse_hid_descr(usb_hid_descr_t *, size_t, 93 usb_alt_if_data_t *, usb_ep_data_t *); 94 static int hid_parse_hid_descr_failure(hid_state_t *); 95 static int hid_handle_report_descriptor(hid_state_t *, int); 96 static void hid_set_idle(hid_state_t *); 97 static void hid_set_protocol(hid_state_t *, int); 98 static void hid_detach_cleanup(dev_info_t *, hid_state_t *); 99 100 static int hid_start_intr_polling(hid_state_t *); 101 static void hid_close_intr_pipe(hid_state_t *); 102 static int hid_mctl_execute_cmd(queue_t *, int, hid_req_t *, 103 mblk_t *); 104 static int hid_mctl_receive(queue_t *, mblk_t *); 105 static int hid_send_async_ctrl_request(hid_default_pipe_arg_t *, hid_req_t *, 106 uchar_t, int, ushort_t); 107 108 static void hid_create_pm_components(dev_info_t *, hid_state_t *); 109 static int hid_is_pm_enabled(dev_info_t *); 110 static void hid_restore_device_state(dev_info_t *, hid_state_t *); 111 static void hid_save_device_state(hid_state_t *); 112 113 static void hid_qreply_merror(queue_t *, mblk_t *, uchar_t); 114 static mblk_t *hid_data2mblk(uchar_t *, int); 115 static void hid_flush(queue_t *); 116 117 static int hid_pwrlvl0(hid_state_t *); 118 static int hid_pwrlvl1(hid_state_t *); 119 static int hid_pwrlvl2(hid_state_t *); 120 static int hid_pwrlvl3(hid_state_t *); 121 static void hid_pm_busy_component(hid_state_t *); 122 static void hid_pm_idle_component(hid_state_t *); 123 124 static int hid_polled_read(hid_polled_handle_t, uchar_t **); 125 static int hid_polled_input_enter(hid_polled_handle_t); 126 static int hid_polled_input_exit(hid_polled_handle_t); 127 static int hid_polled_input_init(hid_state_t *); 128 static int hid_polled_input_fini(hid_state_t *); 129 130 /* Streams entry points */ 131 static int hid_open(queue_t *, dev_t *, int, int, cred_t *); 132 static int hid_close(queue_t *, int, cred_t *); 133 static int hid_wput(queue_t *, mblk_t *); 134 static int hid_wsrv(queue_t *); 135 136 /* dev_ops entry points */ 137 static int hid_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 138 static int hid_attach(dev_info_t *, ddi_attach_cmd_t); 139 static int hid_detach(dev_info_t *, ddi_detach_cmd_t); 140 static int hid_power(dev_info_t *, int, int); 141 142 /* 143 * Warlock is not aware of the automatic locking mechanisms for 144 * streams drivers. The hid streams enter points are protected by 145 * a per module perimeter. If the locking in hid is a bottleneck 146 * per queue pair or per queue locking may be used. Since warlock 147 * is not aware of the streams perimeters, these notes have been added. 148 * 149 * Note that the perimeters do not protect the driver from callbacks 150 * happening while a streams entry point is executing. So, the hid_mutex 151 * has been created to protect the data. 152 */ 153 _NOTE(SCHEME_PROTECTS_DATA("unique per call", iocblk)) 154 _NOTE(SCHEME_PROTECTS_DATA("unique per call", datab)) 155 _NOTE(SCHEME_PROTECTS_DATA("unique per call", msgb)) 156 _NOTE(SCHEME_PROTECTS_DATA("unique per call", queue)) 157 _NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_ctrl_req)) 158 _NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_intr_req)) 159 160 /* module information */ 161 static struct module_info hid_mod_info = { 162 0x0ffff, /* module id number */ 163 "hid", /* module name */ 164 0, /* min packet size accepted */ 165 INFPSZ, /* max packet size accepted */ 166 512, /* hi-water mark */ 167 128 /* lo-water mark */ 168 }; 169 170 /* read queue information structure */ 171 static struct qinit rinit = { 172 NULL, /* put procedure not needed */ 173 NULL, /* service procedure not needed */ 174 hid_open, /* called on startup */ 175 hid_close, /* called on finish */ 176 NULL, /* for future use */ 177 &hid_mod_info, /* module information structure */ 178 NULL /* module statistics structure */ 179 }; 180 181 /* write queue information structure */ 182 static struct qinit winit = { 183 hid_wput, /* put procedure */ 184 hid_wsrv, /* service procedure */ 185 NULL, /* open not used on write side */ 186 NULL, /* close not used on write side */ 187 NULL, /* for future use */ 188 &hid_mod_info, /* module information structure */ 189 NULL /* module statistics structure */ 190 }; 191 192 struct streamtab hid_streamtab = { 193 &rinit, 194 &winit, 195 NULL, /* not a MUX */ 196 NULL /* not a MUX */ 197 }; 198 199 struct cb_ops hid_cb_ops = { 200 nulldev, /* open */ 201 nulldev, /* close */ 202 nulldev, /* strategy */ 203 nulldev, /* print */ 204 nulldev, /* dump */ 205 nulldev, /* read */ 206 nulldev, /* write */ 207 nulldev, /* ioctl */ 208 nulldev, /* devmap */ 209 nulldev, /* mmap */ 210 nulldev, /* segmap */ 211 nochpoll, /* poll */ 212 ddi_prop_op, /* cb_prop_op */ 213 &hid_streamtab, /* streamtab */ 214 D_MP | D_MTPERQ 215 }; 216 217 218 static struct dev_ops hid_ops = { 219 DEVO_REV, /* devo_rev, */ 220 0, /* refcnt */ 221 hid_info, /* info */ 222 nulldev, /* identify */ 223 nulldev, /* probe */ 224 hid_attach, /* attach */ 225 hid_detach, /* detach */ 226 nodev, /* reset */ 227 &hid_cb_ops, /* driver operations */ 228 NULL, /* bus operations */ 229 hid_power, /* power */ 230 ddi_quiesce_not_needed, /* quiesce */ 231 }; 232 233 static struct modldrv hidmodldrv = { 234 &mod_driverops, 235 "USB HID Client Driver", 236 &hid_ops /* driver ops */ 237 }; 238 239 static struct modlinkage modlinkage = { 240 MODREV_1, 241 { &hidmodldrv, NULL } 242 }; 243 244 static usb_event_t hid_events = { 245 hid_disconnect_event_callback, 246 hid_restore_state_event_callback, 247 NULL, 248 NULL, 249 }; 250 251 252 int 253 _init(void) 254 { 255 int rval; 256 257 if (((rval = ddi_soft_state_init(&hid_statep, sizeof (hid_state_t), 258 HID_INITIAL_SOFT_SPACE)) != 0)) { 259 260 return (rval); 261 } 262 263 if ((rval = mod_install(&modlinkage)) != 0) { 264 ddi_soft_state_fini(&hid_statep); 265 } 266 267 return (rval); 268 } 269 270 271 int 272 _fini(void) 273 { 274 int rval; 275 276 if ((rval = mod_remove(&modlinkage)) != 0) { 277 278 return (rval); 279 } 280 281 ddi_soft_state_fini(&hid_statep); 282 283 return (rval); 284 } 285 286 287 int 288 _info(struct modinfo *modinfop) 289 { 290 return (mod_info(&modlinkage, modinfop)); 291 } 292 293 294 /* 295 * hid_info : 296 * Get minor number, soft state structure etc. 297 */ 298 /*ARGSUSED*/ 299 static int 300 hid_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 301 void *arg, void **result) 302 { 303 hid_state_t *hidp = NULL; 304 int error = DDI_FAILURE; 305 minor_t minor = getminor((dev_t)arg); 306 int instance = HID_MINOR_TO_INSTANCE(minor); 307 308 switch (infocmd) { 309 case DDI_INFO_DEVT2DEVINFO: 310 if ((hidp = ddi_get_soft_state(hid_statep, instance)) != NULL) { 311 *result = hidp->hid_dip; 312 if (*result != NULL) { 313 error = DDI_SUCCESS; 314 } 315 } else 316 *result = NULL; 317 break; 318 case DDI_INFO_DEVT2INSTANCE: 319 *result = (void *)(uintptr_t)instance; 320 error = DDI_SUCCESS; 321 break; 322 default: 323 break; 324 } 325 326 return (error); 327 } 328 329 330 /* 331 * hid_attach : 332 * Gets called at the time of attach. Do allocation, 333 * and initialization of the software structure. 334 * Get all the descriptors, setup the 335 * report descriptor tree by calling hidparser 336 * function. 337 */ 338 static int 339 hid_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 340 { 341 342 int instance = ddi_get_instance(dip); 343 int parse_hid_descr_error = 0; 344 hid_state_t *hidp = NULL; 345 uint32_t usage_page; 346 uint32_t usage; 347 usb_client_dev_data_t *dev_data; 348 usb_alt_if_data_t *altif_data; 349 char minor_name[HID_MINOR_NAME_LEN]; 350 usb_ep_data_t *ep_data; 351 352 switch (cmd) { 353 case DDI_ATTACH: 354 break; 355 case DDI_RESUME: 356 hidp = ddi_get_soft_state(hid_statep, instance); 357 hid_cpr_resume(hidp); 358 return (DDI_SUCCESS); 359 default: 360 361 return (DDI_FAILURE); 362 } 363 364 /* 365 * Allocate softstate information and get softstate pointer 366 */ 367 if (ddi_soft_state_zalloc(hid_statep, instance) == DDI_SUCCESS) { 368 hidp = ddi_get_soft_state(hid_statep, instance); 369 } 370 if (hidp == NULL) { 371 372 goto fail; 373 } 374 375 hidp->hid_log_handle = usb_alloc_log_hdl(dip, NULL, &hid_errlevel, 376 &hid_errmask, &hid_instance_debug, 0); 377 378 hidp->hid_instance = instance; 379 hidp->hid_dip = dip; 380 381 /* 382 * Register with USBA. Just retrieve interface descriptor 383 */ 384 if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) { 385 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 386 "hid_attach: client attach failed"); 387 388 goto fail; 389 } 390 391 if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) != 392 USB_SUCCESS) { 393 394 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 395 "hid_attach: usb_get_dev_data() failed"); 396 397 goto fail; 398 } 399 400 /* initialize mutex */ 401 mutex_init(&hidp->hid_mutex, NULL, MUTEX_DRIVER, 402 dev_data->dev_iblock_cookie); 403 404 hidp->hid_attach_flags |= HID_LOCK_INIT; 405 406 /* get interface data for alternate 0 */ 407 altif_data = &dev_data->dev_curr_cfg-> 408 cfg_if[dev_data->dev_curr_if].if_alt[0]; 409 410 mutex_enter(&hidp->hid_mutex); 411 hidp->hid_dev_data = dev_data; 412 hidp->hid_dev_descr = dev_data->dev_descr; 413 hidp->hid_interfaceno = dev_data->dev_curr_if; 414 hidp->hid_if_descr = altif_data->altif_descr; 415 /* 416 * Make sure that the bInterfaceProtocol only has meaning to 417 * Boot Interface Subclass. 418 */ 419 if (hidp->hid_if_descr.bInterfaceSubClass != BOOT_INTERFACE) 420 hidp->hid_if_descr.bInterfaceProtocol = NONE_PROTOCOL; 421 mutex_exit(&hidp->hid_mutex); 422 423 if ((ep_data = usb_lookup_ep_data(dip, dev_data, 424 hidp->hid_interfaceno, 0, 0, 425 (uint_t)USB_EP_ATTR_INTR, (uint_t)USB_EP_DIR_IN)) == NULL) { 426 427 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 428 "no interrupt IN endpoint found"); 429 430 goto fail; 431 } 432 433 mutex_enter(&hidp->hid_mutex); 434 hidp->hid_ep_intr_descr = ep_data->ep_descr; 435 436 /* 437 * Attempt to find the hid descriptor, it could be after interface 438 * or after endpoint descriptors 439 */ 440 if (hid_parse_hid_descr(&hidp->hid_hid_descr, USB_HID_DESCR_SIZE, 441 altif_data, ep_data) != USB_HID_DESCR_SIZE) { 442 /* 443 * If parsing of hid descriptor failed and 444 * the device is a keyboard or mouse, use predefined 445 * length and packet size. 446 */ 447 if (hid_parse_hid_descr_failure(hidp) == USB_FAILURE) { 448 mutex_exit(&hidp->hid_mutex); 449 450 goto fail; 451 } 452 453 /* 454 * hid descriptor was bad but since 455 * the device is a keyboard or mouse, 456 * we will use the default length 457 * and packet size. 458 */ 459 parse_hid_descr_error = HID_BAD_DESCR; 460 } else { 461 /* Parse hid descriptor successful */ 462 463 USB_DPRINTF_L3(PRINT_MASK_ATTA, hidp->hid_log_handle, 464 "Hid descriptor:\n\t" 465 "bLength = 0x%x bDescriptorType = 0x%x " 466 "bcdHID = 0x%x\n\t" 467 "bCountryCode = 0x%x bNumDescriptors = 0x%x\n\t" 468 "bReportDescriptorType = 0x%x\n\t" 469 "wReportDescriptorLength = 0x%x", 470 hidp->hid_hid_descr.bLength, 471 hidp->hid_hid_descr.bDescriptorType, 472 hidp->hid_hid_descr.bcdHID, 473 hidp->hid_hid_descr.bCountryCode, 474 hidp->hid_hid_descr.bNumDescriptors, 475 hidp->hid_hid_descr.bReportDescriptorType, 476 hidp->hid_hid_descr.wReportDescriptorLength); 477 } 478 479 /* 480 * Save a copy of the default pipe for easy reference 481 */ 482 hidp->hid_default_pipe = hidp->hid_dev_data->dev_default_ph; 483 484 /* we copied the descriptors we need, free the dev_data */ 485 usb_free_dev_data(dip, dev_data); 486 hidp->hid_dev_data = NULL; 487 488 /* 489 * Don't get the report descriptor if parsing hid descriptor earlier 490 * failed since device probably won't return valid report descriptor 491 * either. Though parsing of hid descriptor failed, we have reached 492 * this point because the device has been identified as a 493 * keyboard or a mouse successfully and the default packet 494 * size and layout(in case of keyboard only) will be used, so it 495 * is ok to go ahead even if parsing of hid descriptor failed and 496 * we will not try to get the report descriptor. 497 */ 498 if (parse_hid_descr_error != HID_BAD_DESCR) { 499 /* 500 * Sun mouse rev 105 is a bit slow in responding to this 501 * request and requires multiple retries 502 */ 503 int retry; 504 505 /* 506 * Get and parse the report descriptor. 507 * Set the packet size if parsing is successful. 508 * Note that we start retry at 1 to have a delay 509 * in the first iteration. 510 */ 511 mutex_exit(&hidp->hid_mutex); 512 for (retry = 1; retry < HID_RETRY; retry++) { 513 if (hid_handle_report_descriptor(hidp, 514 hidp->hid_interfaceno) == USB_SUCCESS) { 515 break; 516 } 517 delay(retry * drv_usectohz(1000)); 518 } 519 if (retry >= HID_RETRY) { 520 521 goto fail; 522 } 523 mutex_enter(&hidp->hid_mutex); 524 525 /* 526 * If packet size is zero, but the device is identified 527 * as a mouse or a keyboard, use predefined packet 528 * size. 529 */ 530 if (hidp->hid_packet_size == 0) { 531 if (hidp->hid_if_descr.bInterfaceProtocol == 532 KEYBOARD_PROTOCOL) { 533 /* device is a keyboard */ 534 hidp->hid_packet_size = USBKPSZ; 535 } else if (hidp-> 536 hid_if_descr.bInterfaceProtocol == 537 MOUSE_PROTOCOL) { 538 /* device is a mouse */ 539 hidp->hid_packet_size = USBMSSZ; 540 } else { 541 USB_DPRINTF_L2(PRINT_MASK_ATTA, 542 hidp->hid_log_handle, 543 "Failed to find hid packet size"); 544 mutex_exit(&hidp->hid_mutex); 545 546 goto fail; 547 } 548 } 549 } 550 551 /* 552 * initialize the pipe policy for the interrupt pipe. 553 */ 554 hidp->hid_intr_pipe_policy.pp_max_async_reqs = 1; 555 556 /* 557 * Make a clas specific request to SET_IDLE 558 * In this case send no reports if state has not changed. 559 * See HID 7.2.4. 560 */ 561 mutex_exit(&hidp->hid_mutex); 562 hid_set_idle(hidp); 563 564 /* always initialize to report protocol */ 565 hid_set_protocol(hidp, SET_REPORT_PROTOCOL); 566 mutex_enter(&hidp->hid_mutex); 567 568 /* 569 * Create minor node based on information from the 570 * descriptors 571 */ 572 switch (hidp->hid_if_descr.bInterfaceProtocol) { 573 case KEYBOARD_PROTOCOL: 574 (void) strcpy(minor_name, "keyboard"); 575 576 break; 577 case MOUSE_PROTOCOL: 578 (void) strcpy(minor_name, "mouse"); 579 580 break; 581 default: 582 /* 583 * If the report descriptor has the GD mouse collection in 584 * its multiple collection, create a minor node and support it. 585 * It is used on some advanced keyboard/mouse set. 586 */ 587 if (hidparser_lookup_usage_collection( 588 hidp->hid_report_descr, HID_GENERIC_DESKTOP, 589 HID_GD_MOUSE) != HIDPARSER_FAILURE) { 590 (void) strcpy(minor_name, "mouse"); 591 592 break; 593 } 594 595 if (hidparser_get_top_level_collection_usage( 596 hidp->hid_report_descr, &usage_page, &usage) != 597 HIDPARSER_FAILURE) { 598 switch (usage_page) { 599 case HID_CONSUMER: 600 switch (usage) { 601 case HID_CONSUMER_CONTROL: 602 (void) strcpy(minor_name, 603 "consumer_control"); 604 605 break; 606 default: 607 (void) sprintf(minor_name, 608 "hid_%d_%d", usage_page, usage); 609 610 break; 611 } 612 613 break; 614 case HID_GENERIC_DESKTOP: 615 switch (usage) { 616 case HID_GD_POINTER: 617 (void) strcpy(minor_name, 618 "pointer"); 619 620 break; 621 case HID_GD_MOUSE: 622 (void) strcpy(minor_name, 623 "mouse"); 624 625 break; 626 case HID_GD_KEYBOARD: 627 (void) strcpy(minor_name, 628 "keyboard"); 629 630 break; 631 default: 632 (void) sprintf(minor_name, 633 "hid_%d_%d", usage_page, usage); 634 635 break; 636 } 637 638 break; 639 default: 640 (void) sprintf(minor_name, 641 "hid_%d_%d", usage_page, usage); 642 643 break; 644 } 645 } else { 646 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 647 "hid_attach: Unsupported HID device"); 648 mutex_exit(&hidp->hid_mutex); 649 650 goto fail; 651 } 652 653 break; 654 } 655 656 mutex_exit(&hidp->hid_mutex); 657 658 if ((ddi_create_minor_node(dip, minor_name, S_IFCHR, 659 HID_CONSTRUCT_EXTERNAL_MINOR(instance), 660 DDI_PSEUDO, 0)) != DDI_SUCCESS) { 661 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 662 "hid_attach: Could not create minor node"); 663 664 goto fail; 665 } 666 667 /* create internal path for virtual */ 668 if (strcmp(minor_name, "mouse") == 0) { 669 if (ddi_create_internal_pathname(dip, "internal_mouse", S_IFCHR, 670 HID_CONSTRUCT_INTERNAL_MINOR(instance)) != DDI_SUCCESS) { 671 672 goto fail; 673 } 674 } 675 676 if (strcmp(minor_name, "keyboard") == 0) { 677 if (ddi_create_internal_pathname(dip, "internal_keyboard", 678 S_IFCHR, HID_CONSTRUCT_INTERNAL_MINOR(instance)) != 679 DDI_SUCCESS) { 680 681 goto fail; 682 } 683 } 684 685 mutex_enter(&hidp->hid_mutex); 686 hidp->hid_attach_flags |= HID_MINOR_NODES; 687 hidp->hid_dev_state = USB_DEV_ONLINE; 688 mutex_exit(&hidp->hid_mutex); 689 690 /* register for all events */ 691 if (usb_register_event_cbs(dip, &hid_events, 0) != USB_SUCCESS) { 692 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 693 "usb_register_event_cbs failed"); 694 695 goto fail; 696 } 697 698 /* now create components to power manage this device */ 699 hid_create_pm_components(dip, hidp); 700 hid_pm_busy_component(hidp); 701 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 702 hid_pm_idle_component(hidp); 703 704 hidp->hid_internal_rq = hidp->hid_external_rq = NULL; 705 hidp->hid_internal_flag = hidp->hid_external_flag = 0; 706 hidp->hid_inuse_rq = NULL; 707 708 /* 709 * report device 710 */ 711 ddi_report_dev(dip); 712 713 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 714 "hid_attach: End"); 715 716 return (DDI_SUCCESS); 717 718 fail: 719 if (hidp) { 720 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 721 "hid_attach: fail"); 722 hid_detach_cleanup(dip, hidp); 723 } 724 725 return (DDI_FAILURE); 726 } 727 728 729 /* 730 * hid_detach : 731 * Gets called at the time of detach. 732 */ 733 static int 734 hid_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 735 { 736 int instance = ddi_get_instance(dip); 737 hid_state_t *hidp; 738 int rval = DDI_FAILURE; 739 740 hidp = ddi_get_soft_state(hid_statep, instance); 741 742 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, "hid_detach"); 743 744 switch (cmd) { 745 case DDI_DETACH: 746 /* 747 * Undo what we did in client_attach, freeing resources 748 * and removing things we installed. The system 749 * framework guarantees we are not active with this devinfo 750 * node in any other entry points at this time. 751 */ 752 hid_detach_cleanup(dip, hidp); 753 754 return (DDI_SUCCESS); 755 case DDI_SUSPEND: 756 rval = hid_cpr_suspend(hidp); 757 758 return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE); 759 default: 760 break; 761 } 762 763 return (rval); 764 } 765 766 /* 767 * hid_open : 768 * Open entry point: Opens the interrupt pipe. Sets up queues. 769 */ 770 /*ARGSUSED*/ 771 static int 772 hid_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) 773 { 774 int no_of_ep = 0; 775 int rval; 776 int instance; 777 hid_state_t *hidp; 778 minor_t minor = getminor(*devp); 779 780 instance = HID_MINOR_TO_INSTANCE(minor); 781 782 hidp = ddi_get_soft_state(hid_statep, instance); 783 if (hidp == NULL) { 784 785 return (ENXIO); 786 } 787 788 USB_DPRINTF_L4(PRINT_MASK_OPEN, hidp->hid_log_handle, 789 "hid_open: Begin"); 790 791 if (sflag) { 792 /* clone open NOT supported here */ 793 return (ENXIO); 794 } 795 796 if (!(flag & FREAD)) { 797 return (EIO); 798 } 799 800 /* 801 * This is a workaround: 802 * Currently, if we open an already disconnected device, and send 803 * a CONSOPENPOLL ioctl to it, the system will panic, please refer 804 * to the processing HID_OPEN_POLLED_INPUT ioctl in the routine 805 * hid_mctl_receive(). 806 * The consconfig_dacf module need this interface to detect if the 807 * device is already disconnnected. 808 */ 809 mutex_enter(&hidp->hid_mutex); 810 if (HID_IS_INTERNAL_OPEN(minor) && 811 (hidp->hid_dev_state == USB_DEV_DISCONNECTED)) { 812 mutex_exit(&hidp->hid_mutex); 813 return (ENODEV); 814 } 815 816 if (HID_IS_INTERNAL_OPEN(minor) && 817 (hidp->hid_internal_rq != NULL)) { 818 ASSERT(hidp->hid_internal_rq == q); 819 820 mutex_exit(&hidp->hid_mutex); 821 return (0); 822 } 823 824 if ((!HID_IS_INTERNAL_OPEN(minor)) && 825 (hidp->hid_external_rq != NULL)) { 826 ASSERT(hidp->hid_external_rq == q); 827 828 mutex_exit(&hidp->hid_mutex); 829 return (0); 830 } 831 832 mutex_exit(&hidp->hid_mutex); 833 834 q->q_ptr = hidp; 835 WR(q)->q_ptr = hidp; 836 837 mutex_enter(&hidp->hid_mutex); 838 if (hidp->hid_inuse_rq != NULL) { 839 /* Pipe has already been setup */ 840 841 if (HID_IS_INTERNAL_OPEN(minor)) { 842 hidp->hid_internal_flag = HID_STREAMS_OPEN; 843 hidp->hid_inuse_rq = hidp->hid_internal_rq = q; 844 } else { 845 hidp->hid_external_flag = HID_STREAMS_OPEN; 846 hidp->hid_inuse_rq = hidp->hid_external_rq = q; 847 } 848 849 mutex_exit(&hidp->hid_mutex); 850 851 qprocson(q); 852 853 return (0); 854 } 855 856 /* Pipe only needs to be opened once */ 857 hidp->hid_interrupt_pipe = NULL; 858 no_of_ep = hidp->hid_if_descr.bNumEndpoints; 859 mutex_exit(&hidp->hid_mutex); 860 861 /* Check if interrupt endpoint exists */ 862 if (no_of_ep > 0) { 863 /* Open the interrupt pipe */ 864 if (usb_pipe_open(hidp->hid_dip, 865 &hidp->hid_ep_intr_descr, 866 &hidp->hid_intr_pipe_policy, USB_FLAGS_SLEEP, 867 &hidp->hid_interrupt_pipe) != 868 USB_SUCCESS) { 869 870 q->q_ptr = NULL; 871 WR(q)->q_ptr = NULL; 872 return (EIO); 873 } 874 } 875 876 hid_pm_busy_component(hidp); 877 (void) pm_raise_power(hidp->hid_dip, 0, USB_DEV_OS_FULL_PWR); 878 879 mutex_enter(&hidp->hid_mutex); 880 if (HID_IS_INTERNAL_OPEN(minor)) { 881 hidp->hid_internal_flag = HID_STREAMS_OPEN; 882 hidp->hid_inuse_rq = hidp->hid_internal_rq = q; 883 } else { 884 hidp->hid_external_flag = HID_STREAMS_OPEN; 885 hidp->hid_inuse_rq = hidp->hid_external_rq = q; 886 } 887 888 mutex_exit(&hidp->hid_mutex); 889 890 qprocson(q); 891 892 mutex_enter(&hidp->hid_mutex); 893 894 if ((rval = hid_start_intr_polling(hidp)) != USB_SUCCESS) { 895 USB_DPRINTF_L2(PRINT_MASK_OPEN, hidp->hid_log_handle, 896 "unable to start intr pipe polling. rval = %d", rval); 897 898 if (HID_IS_INTERNAL_OPEN(minor)) 899 hidp->hid_internal_flag = HID_STREAMS_DISMANTLING; 900 else 901 hidp->hid_external_flag = HID_STREAMS_DISMANTLING; 902 mutex_exit(&hidp->hid_mutex); 903 904 usb_pipe_close(hidp->hid_dip, hidp->hid_interrupt_pipe, 905 USB_FLAGS_SLEEP, NULL, NULL); 906 907 mutex_enter(&hidp->hid_mutex); 908 hidp->hid_interrupt_pipe = NULL; 909 mutex_exit(&hidp->hid_mutex); 910 911 qprocsoff(q); 912 913 mutex_enter(&hidp->hid_mutex); 914 if (HID_IS_INTERNAL_OPEN(minor)) { 915 hidp->hid_internal_flag = 0; 916 hidp->hid_internal_rq = NULL; 917 if (hidp->hid_external_flag == HID_STREAMS_OPEN) 918 hidp->hid_inuse_rq = hidp->hid_external_rq; 919 else 920 hidp->hid_inuse_rq = NULL; 921 } else { 922 hidp->hid_external_flag = 0; 923 hidp->hid_external_rq = NULL; 924 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) 925 hidp->hid_inuse_rq = hidp->hid_internal_rq; 926 else 927 hidp->hid_inuse_rq = NULL; 928 } 929 mutex_exit(&hidp->hid_mutex); 930 931 q->q_ptr = NULL; 932 WR(q)->q_ptr = NULL; 933 934 hid_pm_idle_component(hidp); 935 936 return (EIO); 937 } 938 mutex_exit(&hidp->hid_mutex); 939 940 USB_DPRINTF_L4(PRINT_MASK_OPEN, hidp->hid_log_handle, "hid_open: End"); 941 942 /* 943 * Keyboard and mouse is Power managed by device activity. 944 * All other devices go busy on open and idle on close. 945 */ 946 switch (hidp->hid_pm->hid_pm_strategy) { 947 case HID_PM_ACTIVITY: 948 hid_pm_idle_component(hidp); 949 950 break; 951 default: 952 953 break; 954 } 955 956 return (0); 957 } 958 959 960 /* 961 * hid_close : 962 * Close entry point. 963 */ 964 /*ARGSUSED*/ 965 static int 966 hid_close(queue_t *q, int flag, cred_t *credp) 967 { 968 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 969 queue_t *wq; 970 mblk_t *mp; 971 972 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, "hid_close:"); 973 974 mutex_enter(&hidp->hid_mutex); 975 976 ASSERT((hidp->hid_internal_rq == q) || 977 (hidp->hid_external_rq == q)); 978 979 if (hidp->hid_internal_rq == q) 980 hidp->hid_internal_flag = HID_STREAMS_DISMANTLING; 981 else 982 hidp->hid_external_flag = HID_STREAMS_DISMANTLING; 983 984 mutex_exit(&hidp->hid_mutex); 985 986 /* 987 * In case there are any outstanding requests on 988 * the default pipe, wait forever for them to complete. 989 */ 990 (void) usb_pipe_drain_reqs(hidp->hid_dip, 991 hidp->hid_default_pipe, 0, USB_FLAGS_SLEEP, NULL, 0); 992 993 mutex_enter(&hidp->hid_mutex); 994 wq = WR(q); 995 /* drain any M_CTLS on the WQ */ 996 while (mp = getq(wq)) { 997 hid_qreply_merror(wq, mp, EIO); 998 mutex_exit(&hidp->hid_mutex); 999 hid_pm_idle_component(hidp); 1000 mutex_enter(&hidp->hid_mutex); 1001 } 1002 mutex_exit(&hidp->hid_mutex); 1003 1004 qprocsoff(q); 1005 1006 q->q_ptr = NULL; 1007 wq->q_ptr = NULL; 1008 1009 mutex_enter(&hidp->hid_mutex); 1010 1011 if (hidp->hid_internal_rq == q) { 1012 hidp->hid_internal_rq = NULL; 1013 hidp->hid_internal_flag = 0; 1014 if (hidp->hid_inuse_rq == q) { 1015 /* We are closing the active stream */ 1016 if (hidp->hid_external_flag == HID_STREAMS_OPEN) 1017 hidp->hid_inuse_rq = hidp->hid_external_rq; 1018 else 1019 hidp->hid_inuse_rq = NULL; 1020 } 1021 } else { 1022 hidp->hid_external_rq = NULL; 1023 hidp->hid_external_flag = 0; 1024 if (hidp->hid_inuse_rq == q) { 1025 /* We are closing the active stream */ 1026 if (hidp->hid_internal_flag == HID_STREAMS_OPEN) 1027 hidp->hid_inuse_rq = hidp->hid_internal_rq; 1028 else 1029 hidp->hid_inuse_rq = NULL; 1030 } 1031 } 1032 1033 if (hidp->hid_inuse_rq != NULL) { 1034 mutex_exit(&hidp->hid_mutex); 1035 return (0); 1036 } 1037 1038 /* all queues are closed, close USB pipes */ 1039 hid_close_intr_pipe(hidp); 1040 mutex_exit(&hidp->hid_mutex); 1041 1042 /* 1043 * Devices other than keyboard/mouse go idle on close. 1044 */ 1045 switch (hidp->hid_pm->hid_pm_strategy) { 1046 case HID_PM_ACTIVITY: 1047 1048 break; 1049 default: 1050 hid_pm_idle_component(hidp); 1051 1052 break; 1053 } 1054 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 1055 "hid_close: End"); 1056 1057 return (0); 1058 } 1059 1060 1061 /* 1062 * hid_wput : 1063 * write put routine for the hid module 1064 */ 1065 static int 1066 hid_wput(queue_t *q, mblk_t *mp) 1067 { 1068 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 1069 int error = USB_SUCCESS; 1070 struct iocblk *iocbp; 1071 mblk_t *datap; 1072 int direction; 1073 struct copyresp *crp; 1074 queue_t *tmpq; 1075 int flag; 1076 1077 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1078 "hid_wput: Begin"); 1079 1080 /* See if the upper module is passing the right thing */ 1081 ASSERT(mp != NULL); 1082 ASSERT(mp->b_datap != NULL); 1083 1084 switch (mp->b_datap->db_type) { 1085 case M_FLUSH: /* Canonical flush handling */ 1086 if (*mp->b_rptr & FLUSHW) { 1087 flushq(q, FLUSHDATA); 1088 } 1089 1090 /* read queue not used so just send up */ 1091 if (*mp->b_rptr & FLUSHR) { 1092 *mp->b_rptr &= ~FLUSHW; 1093 qreply(q, mp); 1094 } else { 1095 freemsg(mp); 1096 } 1097 1098 break; 1099 case M_IOCTL: 1100 iocbp = (struct iocblk *)mp->b_rptr; 1101 1102 /* Only accept transparent ioctls */ 1103 if (iocbp->ioc_count != TRANSPARENT) { 1104 miocnak(q, mp, 0, EINVAL); 1105 break; 1106 } 1107 1108 switch (iocbp->ioc_cmd) { 1109 case HIDIOCKMGDIRECT: 1110 1111 mutex_enter(&hidp->hid_mutex); 1112 ASSERT(hidp->hid_inuse_rq != NULL); 1113 mutex_exit(&hidp->hid_mutex); 1114 1115 if ((datap = allocb(sizeof (int), BPRI_MED)) == NULL) { 1116 miocnak(q, mp, 0, ENOMEM); 1117 break; 1118 } 1119 1120 mutex_enter(&hidp->hid_mutex); 1121 if (hidp->hid_inuse_rq == hidp->hid_internal_rq) { 1122 *(int *)datap->b_wptr = 0; 1123 datap->b_wptr += sizeof (int); 1124 } else { 1125 ASSERT(hidp->hid_inuse_rq == 1126 hidp->hid_external_rq); 1127 *(int *)datap->b_wptr = 1; 1128 datap->b_wptr += sizeof (int); 1129 } 1130 mutex_exit(&hidp->hid_mutex); 1131 1132 mcopyout(mp, NULL, sizeof (int), NULL, datap); 1133 qreply(q, mp); 1134 break; 1135 1136 case HIDIOCKMSDIRECT: 1137 mcopyin(mp, NULL, sizeof (int), NULL); 1138 qreply(q, mp); 1139 break; 1140 1141 default: 1142 miocnak(q, mp, 0, ENOTTY); 1143 } 1144 1145 break; 1146 1147 case M_IOCDATA: 1148 1149 crp = (void *)mp->b_rptr; 1150 1151 if (crp->cp_rval != 0) { 1152 miocnak(q, mp, 0, EIO); 1153 break; 1154 } 1155 1156 switch (crp->cp_cmd) { 1157 case HIDIOCKMGDIRECT: 1158 miocack(q, mp, 0, 0); 1159 break; 1160 1161 case HIDIOCKMSDIRECT: 1162 direction = *(int *)mp->b_cont->b_rptr; 1163 1164 if ((direction != 0) && (direction != 1)) { 1165 miocnak(q, mp, 0, EINVAL); 1166 break; 1167 } 1168 1169 mutex_enter(&hidp->hid_mutex); 1170 1171 if (direction == 0) { 1172 /* The internal stream is made active */ 1173 flag = hidp->hid_internal_flag; 1174 tmpq = hidp->hid_internal_rq; 1175 } else { 1176 /* The external stream is made active */ 1177 flag = hidp->hid_external_flag; 1178 tmpq = hidp->hid_external_rq; 1179 } 1180 1181 if (flag != HID_STREAMS_OPEN) { 1182 mutex_exit(&hidp->hid_mutex); 1183 miocnak(q, mp, 0, EIO); 1184 break; 1185 } 1186 1187 hidp->hid_inuse_rq = tmpq; 1188 1189 mutex_exit(&hidp->hid_mutex); 1190 miocack(q, mp, 0, 0); 1191 break; 1192 1193 default: 1194 miocnak(q, mp, 0, ENOTTY); 1195 break; 1196 } 1197 1198 break; 1199 1200 case M_CTL: 1201 /* we are busy now */ 1202 hid_pm_busy_component(hidp); 1203 1204 if (q->q_first) { 1205 (void) putq(q, mp); 1206 } else { 1207 error = hid_mctl_receive(q, mp); 1208 switch (error) { 1209 case HID_ENQUEUE: 1210 /* 1211 * put this mblk on the WQ for the wsrv to 1212 * process 1213 */ 1214 (void) putq(q, mp); 1215 1216 break; 1217 case HID_INPROGRESS: 1218 /* request has been queued to the device */ 1219 1220 break; 1221 case HID_SUCCESS: 1222 /* 1223 * returned by M_CTLS that are processed 1224 * immediately 1225 */ 1226 1227 /* FALLTHRU */ 1228 case HID_FAILURE: 1229 default: 1230 hid_pm_idle_component(hidp); 1231 break; 1232 } 1233 } 1234 break; 1235 default: 1236 hid_qreply_merror(q, mp, EINVAL); 1237 error = USB_FAILURE; 1238 break; 1239 } 1240 1241 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1242 "hid_wput: End"); 1243 1244 return (DDI_SUCCESS); 1245 } 1246 1247 1248 /* 1249 * hid_wsrv : 1250 * Write service routine for hid. When a message arrives through 1251 * hid_wput(), it is kept in write queue to be serviced later. 1252 */ 1253 static int 1254 hid_wsrv(queue_t *q) 1255 { 1256 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 1257 int error; 1258 mblk_t *mp; 1259 1260 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1261 "hid_wsrv: Begin"); 1262 1263 mutex_enter(&hidp->hid_mutex); 1264 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1265 "hid_wsrv: dev_state: %s", 1266 usb_str_dev_state(hidp->hid_dev_state)); 1267 1268 /* 1269 * raise power if we are powered down. It is OK to block here since 1270 * we have a separate thread to process this STREAM 1271 */ 1272 if (hidp->hid_dev_state == USB_DEV_PWRED_DOWN) { 1273 mutex_exit(&hidp->hid_mutex); 1274 (void) pm_raise_power(hidp->hid_dip, 0, USB_DEV_OS_FULL_PWR); 1275 mutex_enter(&hidp->hid_mutex); 1276 } 1277 1278 /* 1279 * continue servicing all the M_CTL's till the queue is empty 1280 * or the device gets disconnected or till a hid_close() 1281 */ 1282 while ((hidp->hid_dev_state == USB_DEV_ONLINE) && 1283 (HID_STREAMS_FLAG(q, hidp) != HID_STREAMS_DISMANTLING) && 1284 ((mp = getq(q)) != NULL)) { 1285 1286 /* Send a message down */ 1287 mutex_exit(&hidp->hid_mutex); 1288 error = hid_mctl_receive(q, mp); 1289 switch (error) { 1290 case HID_ENQUEUE: 1291 /* put this mblk back on q to preserve order */ 1292 (void) putbq(q, mp); 1293 1294 break; 1295 case HID_INPROGRESS: 1296 /* request has been queued to the device */ 1297 1298 break; 1299 case HID_SUCCESS: 1300 case HID_FAILURE: 1301 default: 1302 hid_pm_idle_component(hidp); 1303 1304 break; 1305 } 1306 mutex_enter(&hidp->hid_mutex); 1307 } 1308 mutex_exit(&hidp->hid_mutex); 1309 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1310 "hid_wsrv: End"); 1311 1312 return (DDI_SUCCESS); 1313 } 1314 1315 1316 /* 1317 * hid_power: 1318 * power entry point 1319 */ 1320 static int 1321 hid_power(dev_info_t *dip, int comp, int level) 1322 { 1323 int instance = ddi_get_instance(dip); 1324 hid_state_t *hidp; 1325 hid_power_t *hidpm; 1326 int retval; 1327 1328 hidp = ddi_get_soft_state(hid_statep, instance); 1329 1330 USB_DPRINTF_L3(PRINT_MASK_PM, hidp->hid_log_handle, "hid_power:" 1331 " hid_state: comp=%d level=%d", comp, level); 1332 1333 /* check if we are transitioning to a legal power level */ 1334 mutex_enter(&hidp->hid_mutex); 1335 hidpm = hidp->hid_pm; 1336 1337 if (USB_DEV_PWRSTATE_OK(hidpm->hid_pwr_states, level)) { 1338 1339 USB_DPRINTF_L2(PRINT_MASK_PM, hidp->hid_log_handle, 1340 "hid_power: illegal level=%d hid_pwr_states=%d", 1341 level, hidpm->hid_pwr_states); 1342 1343 mutex_exit(&hidp->hid_mutex); 1344 1345 return (DDI_FAILURE); 1346 } 1347 1348 switch (level) { 1349 case USB_DEV_OS_PWR_OFF: 1350 retval = hid_pwrlvl0(hidp); 1351 break; 1352 case USB_DEV_OS_PWR_1: 1353 retval = hid_pwrlvl1(hidp); 1354 break; 1355 case USB_DEV_OS_PWR_2: 1356 retval = hid_pwrlvl2(hidp); 1357 break; 1358 case USB_DEV_OS_FULL_PWR: 1359 retval = hid_pwrlvl3(hidp); 1360 break; 1361 default: 1362 retval = USB_FAILURE; 1363 break; 1364 } 1365 1366 mutex_exit(&hidp->hid_mutex); 1367 1368 return ((retval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 1369 } 1370 1371 1372 /* 1373 * hid_interrupt_pipe_callback: 1374 * Callback function for the hid intr pipe. This function is called by 1375 * USBA when a buffer has been filled. This driver does not cook the data, 1376 * it just sends the message up. 1377 */ 1378 static void 1379 hid_interrupt_pipe_callback(usb_pipe_handle_t pipe, usb_intr_req_t *req) 1380 { 1381 hid_state_t *hidp = (hid_state_t *)req->intr_client_private; 1382 queue_t *q; 1383 1384 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1385 "hid_interrupt_pipe_callback: ph = 0x%p req = 0x%p", 1386 (void *)pipe, (void *)req); 1387 1388 hid_pm_busy_component(hidp); 1389 1390 mutex_enter(&hidp->hid_mutex); 1391 1392 /* 1393 * If hid_close() is in progress, we shouldn't try accessing queue 1394 * Otherwise indicate that a putnext is going to happen, so 1395 * if close after this, that should wait for the putnext to finish. 1396 */ 1397 if (HID_STREAMS_FLAG(hidp->hid_inuse_rq, hidp) == 1398 HID_STREAMS_OPEN) { 1399 /* 1400 * Check if data can be put to the next queue. 1401 */ 1402 if (!canputnext(hidp->hid_inuse_rq)) { 1403 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1404 "Buffer flushed when overflowed."); 1405 1406 /* Flush the queue above */ 1407 hid_flush(hidp->hid_inuse_rq); 1408 mutex_exit(&hidp->hid_mutex); 1409 } else { 1410 q = hidp->hid_inuse_rq; 1411 mutex_exit(&hidp->hid_mutex); 1412 1413 /* Put data upstream */ 1414 putnext(q, req->intr_data); 1415 1416 /* usb_free_intr_req should not free data */ 1417 req->intr_data = NULL; 1418 } 1419 } else { 1420 mutex_exit(&hidp->hid_mutex); 1421 } 1422 1423 /* free request and data */ 1424 usb_free_intr_req(req); 1425 hid_pm_idle_component(hidp); 1426 } 1427 1428 1429 /* 1430 * hid_default_pipe_callback : 1431 * Callback routine for the asynchronous control transfer 1432 * Called from hid_send_async_ctrl_request() where we open 1433 * the pipe in exclusive mode 1434 */ 1435 static void 1436 hid_default_pipe_callback(usb_pipe_handle_t pipe, usb_ctrl_req_t *req) 1437 { 1438 hid_default_pipe_arg_t *hid_default_pipe_arg = 1439 (hid_default_pipe_arg_t *)req->ctrl_client_private; 1440 queue_t *wq = hid_default_pipe_arg->hid_default_pipe_arg_queue; 1441 queue_t *rq = RD(wq); 1442 hid_state_t *hidp = (hid_state_t *)rq->q_ptr; 1443 mblk_t *mctl_mp; 1444 mblk_t *data = NULL; 1445 1446 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 1447 "hid_default_pipe_callback: " 1448 "ph = 0x%p, req = 0x%p, data= 0x%p", 1449 (void *)pipe, (void *)req, (void *)data); 1450 1451 ASSERT((req->ctrl_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1452 1453 if (req->ctrl_data) { 1454 data = req->ctrl_data; 1455 req->ctrl_data = NULL; 1456 } 1457 1458 /* 1459 * Free the b_cont of the original message that was sent down. 1460 */ 1461 mctl_mp = hid_default_pipe_arg->hid_default_pipe_arg_mblk; 1462 freemsg(mctl_mp->b_cont); 1463 1464 /* chain the mblk received to the original & send it up */ 1465 mctl_mp->b_cont = data; 1466 1467 if (canputnext(rq)) { 1468 putnext(rq, mctl_mp); 1469 } else { 1470 freemsg(mctl_mp); /* avoid leak */ 1471 } 1472 1473 /* 1474 * Free the argument for the asynchronous callback 1475 */ 1476 kmem_free(hid_default_pipe_arg, sizeof (hid_default_pipe_arg_t)); 1477 1478 /* 1479 * Free the control pipe request structure. 1480 */ 1481 usb_free_ctrl_req(req); 1482 1483 mutex_enter(&hidp->hid_mutex); 1484 hidp->hid_default_pipe_req--; 1485 ASSERT(hidp->hid_default_pipe_req >= 0); 1486 mutex_exit(&hidp->hid_mutex); 1487 1488 hid_pm_idle_component(hidp); 1489 qenable(wq); 1490 } 1491 1492 1493 /* 1494 * hid_interrupt_pipe_exception_callback: 1495 * Exception callback routine for interrupt pipe. If there is any data, 1496 * destroy it. No threads are waiting for the exception callback. 1497 */ 1498 /*ARGSUSED*/ 1499 static void 1500 hid_interrupt_pipe_exception_callback(usb_pipe_handle_t pipe, 1501 usb_intr_req_t *req) 1502 { 1503 hid_state_t *hidp = (hid_state_t *)req->intr_client_private; 1504 mblk_t *data = req->intr_data; 1505 usb_cb_flags_t flags = req->intr_cb_flags; 1506 int rval; 1507 1508 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1509 "hid_interrupt_pipe_exception_callback: " 1510 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x", 1511 req->intr_completion_reason, (void *)data, req->intr_cb_flags); 1512 1513 ASSERT((req->intr_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1514 1515 if (((flags & USB_CB_FUNCTIONAL_STALL) != 0) && 1516 ((flags & USB_CB_STALL_CLEARED) == 0)) { 1517 USB_DPRINTF_L2(PRINT_MASK_ALL, 1518 hidp->hid_log_handle, 1519 "hid_interrupt_pipe_exception_callback: " 1520 "unable to clear stall. flags = 0x%x", 1521 req->intr_cb_flags); 1522 } 1523 1524 mutex_enter(&hidp->hid_mutex); 1525 1526 switch (req->intr_completion_reason) { 1527 case USB_CR_STOPPED_POLLING: 1528 case USB_CR_PIPE_CLOSING: 1529 default: 1530 1531 break; 1532 case USB_CR_PIPE_RESET: 1533 case USB_CR_NO_RESOURCES: 1534 if ((hidp->hid_dev_state == USB_DEV_ONLINE) && 1535 ((rval = hid_start_intr_polling(hidp)) != 1536 USB_SUCCESS)) { 1537 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1538 "unable to restart interrupt poll. rval = %d", 1539 rval); 1540 } 1541 1542 break; 1543 } 1544 1545 mutex_exit(&hidp->hid_mutex); 1546 1547 usb_free_intr_req(req); 1548 } 1549 1550 1551 /* 1552 * hid_default_pipe_exception_callback: 1553 * Exception callback routine for default pipe. 1554 */ 1555 /*ARGSUSED*/ 1556 static void 1557 hid_default_pipe_exception_callback(usb_pipe_handle_t pipe, 1558 usb_ctrl_req_t *req) 1559 { 1560 hid_default_pipe_arg_t *hid_default_pipe_arg = 1561 (hid_default_pipe_arg_t *)req->ctrl_client_private; 1562 queue_t *wq = hid_default_pipe_arg->hid_default_pipe_arg_queue; 1563 queue_t *rq = RD(wq); 1564 hid_state_t *hidp = (hid_state_t *)rq->q_ptr; 1565 usb_cr_t ctrl_completion_reason = req->ctrl_completion_reason; 1566 mblk_t *mp, *data = NULL; 1567 1568 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 1569 "hid_default_pipe_exception_callback: " 1570 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x", 1571 ctrl_completion_reason, (void *)data, req->ctrl_cb_flags); 1572 1573 ASSERT((req->ctrl_cb_flags & USB_CB_INTR_CONTEXT) == 0); 1574 1575 mp = hid_default_pipe_arg->hid_default_pipe_arg_mblk; 1576 1577 /* 1578 * Pass an error message up. Reuse existing mblk. 1579 */ 1580 if (canputnext(rq)) { 1581 mp->b_datap->db_type = M_ERROR; 1582 mp->b_rptr = mp->b_datap->db_base; 1583 mp->b_wptr = mp->b_rptr + sizeof (char); 1584 *mp->b_rptr = EIO; 1585 putnext(rq, mp); 1586 } else { 1587 freemsg(mp); 1588 } 1589 1590 kmem_free(hid_default_pipe_arg, sizeof (hid_default_pipe_arg_t)); 1591 1592 mutex_enter(&hidp->hid_mutex); 1593 hidp->hid_default_pipe_req--; 1594 ASSERT(hidp->hid_default_pipe_req >= 0); 1595 mutex_exit(&hidp->hid_mutex); 1596 1597 qenable(wq); 1598 usb_free_ctrl_req(req); 1599 hid_pm_idle_component(hidp); 1600 } 1601 1602 1603 /* 1604 * event handling: 1605 * 1606 * hid_reconnect_event_callback: 1607 * the device was disconnected but this instance not detached, probably 1608 * because the device was busy 1609 * 1610 * If the same device, continue with restoring state 1611 */ 1612 static int 1613 hid_restore_state_event_callback(dev_info_t *dip) 1614 { 1615 hid_state_t *hidp = (hid_state_t *)ddi_get_soft_state(hid_statep, 1616 ddi_get_instance(dip)); 1617 1618 ASSERT(hidp != NULL); 1619 1620 USB_DPRINTF_L3(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1621 "hid_restore_state_event_callback: dip=0x%p", (void *)dip); 1622 1623 hid_restore_device_state(dip, hidp); 1624 1625 return (USB_SUCCESS); 1626 } 1627 1628 1629 /* 1630 * hid_cpr_suspend 1631 * Fail suspend if we can't finish outstanding i/o activity. 1632 */ 1633 static int 1634 hid_cpr_suspend(hid_state_t *hidp) 1635 { 1636 int rval, prev_state; 1637 int retval = USB_FAILURE; 1638 1639 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1640 "hid_cpr_suspend: dip=0x%p", (void *)hidp->hid_dip); 1641 1642 mutex_enter(&hidp->hid_mutex); 1643 switch (hidp->hid_dev_state) { 1644 case USB_DEV_ONLINE: 1645 case USB_DEV_PWRED_DOWN: 1646 prev_state = hidp->hid_dev_state; 1647 hidp->hid_dev_state = USB_DEV_SUSPENDED; 1648 mutex_exit(&hidp->hid_mutex); 1649 1650 /* drain all request outstanding on the default control pipe */ 1651 rval = usb_pipe_drain_reqs(hidp->hid_dip, 1652 hidp->hid_default_pipe, hid_default_pipe_drain_timeout, 1653 USB_FLAGS_SLEEP, NULL, 0); 1654 1655 /* fail checkpoint if we haven't finished the job yet */ 1656 mutex_enter(&hidp->hid_mutex); 1657 if ((rval != USB_SUCCESS) || (hidp->hid_default_pipe_req > 0)) { 1658 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1659 "hid_cpr_suspend: " 1660 "device busy - can't checkpoint"); 1661 1662 /* fall back to previous state */ 1663 hidp->hid_dev_state = prev_state; 1664 } else { 1665 retval = USB_SUCCESS; 1666 hid_save_device_state(hidp); 1667 } 1668 1669 break; 1670 case USB_DEV_DISCONNECTED: 1671 hidp->hid_dev_state = USB_DEV_SUSPENDED; 1672 hid_save_device_state(hidp); 1673 retval = USB_SUCCESS; 1674 break; 1675 case USB_DEV_SUSPENDED: 1676 default: 1677 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1678 "hid_cpr_suspend: Illegal dev state: %d", 1679 hidp->hid_dev_state); 1680 1681 break; 1682 } 1683 mutex_exit(&hidp->hid_mutex); 1684 1685 return (retval); 1686 } 1687 1688 1689 static void 1690 hid_cpr_resume(hid_state_t *hidp) 1691 { 1692 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1693 "hid_cpr_resume: dip=0x%p", (void *)hidp->hid_dip); 1694 1695 hid_restore_device_state(hidp->hid_dip, hidp); 1696 } 1697 1698 1699 /* 1700 * hid_disconnect_event_callback: 1701 * The device has been disconnected. We either wait for 1702 * detach or a reconnect event. Close all pipes and timeouts. 1703 */ 1704 static int 1705 hid_disconnect_event_callback(dev_info_t *dip) 1706 { 1707 hid_state_t *hidp; 1708 mblk_t *mp; 1709 1710 hidp = (hid_state_t *)ddi_get_soft_state(hid_statep, 1711 ddi_get_instance(dip)); 1712 ASSERT(hidp != NULL); 1713 1714 USB_DPRINTF_L4(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1715 "hid_disconnect_event_callback: dip=0x%p", (void *)dip); 1716 1717 mutex_enter(&hidp->hid_mutex); 1718 switch (hidp->hid_dev_state) { 1719 case USB_DEV_ONLINE: 1720 case USB_DEV_PWRED_DOWN: 1721 hidp->hid_dev_state = USB_DEV_DISCONNECTED; 1722 if (HID_IS_OPEN(hidp)) { 1723 1724 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1725 "busy device has been disconnected"); 1726 } 1727 hid_save_device_state(hidp); 1728 1729 /* 1730 * Notify applications about device removal, this only 1731 * applies to an external (aka. physical) open. For an 1732 * internal open, consconfig_dacf closes the queue. 1733 */ 1734 if (hidp->hid_external_flag == HID_STREAMS_OPEN) { 1735 queue_t *q = hidp->hid_external_rq; 1736 mutex_exit(&hidp->hid_mutex); 1737 mp = allocb(sizeof (uchar_t), BPRI_HI); 1738 if (mp != NULL) { 1739 mp->b_datap->db_type = M_ERROR; 1740 mp->b_rptr = mp->b_datap->db_base; 1741 mp->b_wptr = mp->b_rptr + sizeof (char); 1742 *mp->b_rptr = ENODEV; 1743 putnext(q, mp); 1744 } 1745 mutex_enter(&hidp->hid_mutex); 1746 } 1747 1748 break; 1749 case USB_DEV_SUSPENDED: 1750 /* we remain suspended */ 1751 1752 break; 1753 default: 1754 USB_DPRINTF_L2(PRINT_MASK_EVENTS, hidp->hid_log_handle, 1755 "hid_disconnect_event_callback: Illegal dev state: %d", 1756 hidp->hid_dev_state); 1757 1758 break; 1759 } 1760 mutex_exit(&hidp->hid_mutex); 1761 1762 return (USB_SUCCESS); 1763 } 1764 1765 1766 /* 1767 * hid_power_change_callback: 1768 * Async callback function to notify pm_raise_power completion 1769 * after hid_power entry point is called. 1770 */ 1771 static void 1772 hid_power_change_callback(void *arg, int rval) 1773 { 1774 hid_state_t *hidp; 1775 queue_t *wq; 1776 1777 hidp = (hid_state_t *)arg; 1778 1779 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 1780 "hid_power_change_callback - rval: %d", rval); 1781 1782 mutex_enter(&hidp->hid_mutex); 1783 hidp->hid_pm->hid_raise_power = B_FALSE; 1784 1785 if (hidp->hid_dev_state == USB_DEV_ONLINE) { 1786 wq = WR(hidp->hid_inuse_rq); 1787 mutex_exit(&hidp->hid_mutex); 1788 1789 qenable(wq); 1790 1791 } else { 1792 mutex_exit(&hidp->hid_mutex); 1793 } 1794 } 1795 1796 1797 /* 1798 * hid_parse_hid_descr: 1799 * Parse the hid descriptor, check after interface and after 1800 * endpoint descriptor 1801 */ 1802 static size_t 1803 hid_parse_hid_descr( 1804 usb_hid_descr_t *ret_descr, 1805 size_t ret_buf_len, 1806 usb_alt_if_data_t *altif_data, 1807 usb_ep_data_t *ep_data) 1808 { 1809 usb_cvs_data_t *cvs; 1810 int which_cvs; 1811 1812 for (which_cvs = 0; which_cvs < altif_data->altif_n_cvs; which_cvs++) { 1813 cvs = &altif_data->altif_cvs[which_cvs]; 1814 if (cvs->cvs_buf == NULL) { 1815 continue; 1816 } 1817 if (cvs->cvs_buf[1] == USB_DESCR_TYPE_HID) { 1818 return (usb_parse_data("ccscccs", 1819 cvs->cvs_buf, cvs->cvs_buf_len, 1820 (void *)ret_descr, 1821 (size_t)ret_buf_len)); 1822 } 1823 } 1824 1825 /* now try after endpoint */ 1826 for (which_cvs = 0; which_cvs < ep_data->ep_n_cvs; which_cvs++) { 1827 cvs = &ep_data->ep_cvs[which_cvs]; 1828 if (cvs->cvs_buf == NULL) { 1829 continue; 1830 } 1831 if (cvs->cvs_buf[1] == USB_DESCR_TYPE_HID) { 1832 return (usb_parse_data("ccscccs", 1833 cvs->cvs_buf, cvs->cvs_buf_len, 1834 (void *)ret_descr, 1835 (size_t)ret_buf_len)); 1836 } 1837 } 1838 1839 return (USB_PARSE_ERROR); 1840 } 1841 1842 1843 /* 1844 * hid_parse_hid_descr_failure: 1845 * If parsing of hid descriptor failed and the device is 1846 * a keyboard or mouse, use predefined length and packet size. 1847 */ 1848 static int 1849 hid_parse_hid_descr_failure(hid_state_t *hidp) 1850 { 1851 /* 1852 * Parsing hid descriptor failed, probably because the 1853 * device did not return a valid hid descriptor. Check to 1854 * see if this is a keyboard or mouse. If so, use the 1855 * predefined hid descriptor length and packet size. 1856 * Otherwise, detach and return failure. 1857 */ 1858 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 1859 "Parsing of hid descriptor failed"); 1860 1861 if (hidp->hid_if_descr.bInterfaceProtocol == KEYBOARD_PROTOCOL) { 1862 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1863 "Set hid descriptor length to predefined " 1864 "USB_KB_HID_DESCR_LENGTH for keyboard."); 1865 1866 /* device is a keyboard */ 1867 hidp->hid_hid_descr.wReportDescriptorLength = 1868 USB_KB_HID_DESCR_LENGTH; 1869 1870 hidp->hid_packet_size = USBKPSZ; 1871 1872 } else if (hidp->hid_if_descr.bInterfaceProtocol == 1873 MOUSE_PROTOCOL) { 1874 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1875 "Set hid descriptor length to predefined " 1876 "USB_MS_HID_DESCR_LENGTH for mouse."); 1877 1878 /* device is a mouse */ 1879 hidp->hid_hid_descr.wReportDescriptorLength = 1880 USB_MS_HID_DESCR_LENGTH; 1881 1882 hidp->hid_packet_size = USBMSSZ; 1883 } else { 1884 1885 return (USB_FAILURE); 1886 } 1887 1888 return (USB_SUCCESS); 1889 } 1890 1891 1892 /* 1893 * hid_handle_report_descriptor: 1894 * Get the report descriptor, call hidparser routine to parse 1895 * it and query the hidparser tree to get the packet size 1896 */ 1897 static int 1898 hid_handle_report_descriptor(hid_state_t *hidp, 1899 int interface) 1900 { 1901 usb_cr_t completion_reason; 1902 usb_cb_flags_t cb_flags; 1903 mblk_t *data = NULL; 1904 hidparser_packet_info_t hpack; 1905 int i; 1906 usb_ctrl_setup_t setup = { 1907 USB_DEV_REQ_DEV_TO_HOST | /* bmRequestType */ 1908 USB_DEV_REQ_RCPT_IF, 1909 USB_REQ_GET_DESCR, /* bRequest */ 1910 USB_CLASS_DESCR_TYPE_REPORT, /* wValue */ 1911 0, /* wIndex: interface, fill in later */ 1912 0, /* wLength, fill in later */ 1913 0 /* attributes */ 1914 }; 1915 1916 /* 1917 * Parsing hid desciptor was successful earlier. 1918 * Get Report Descriptor 1919 */ 1920 setup.wIndex = (uint16_t)interface; 1921 setup.wLength = hidp->hid_hid_descr.wReportDescriptorLength; 1922 if (usb_pipe_ctrl_xfer_wait(hidp->hid_default_pipe, 1923 &setup, 1924 &data, /* data */ 1925 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 1926 1927 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 1928 "Failed to receive the Report Descriptor"); 1929 freemsg(data); 1930 1931 return (USB_FAILURE); 1932 1933 } else { 1934 int n = hidp->hid_hid_descr.wReportDescriptorLength; 1935 1936 ASSERT(data); 1937 1938 /* Print the report descriptor */ 1939 for (i = 0; i < n; i++) { 1940 USB_DPRINTF_L3(PRINT_MASK_ATTA, hidp->hid_log_handle, 1941 "Index = %d\tvalue =0x%x", i, 1942 (int)(data->b_rptr[i])); 1943 } 1944 1945 /* Get Report Descriptor was successful */ 1946 if (hidparser_parse_report_descriptor( 1947 data->b_rptr, 1948 hidp->hid_hid_descr.wReportDescriptorLength, 1949 &hidp->hid_hid_descr, 1950 &hidp->hid_report_descr) == HIDPARSER_SUCCESS) { 1951 1952 /* find max intr-in xfer length */ 1953 hidparser_find_max_packet_size_from_report_descriptor( 1954 hidp->hid_report_descr, &hpack); 1955 /* round up to the nearest byte */ 1956 hidp->hid_packet_size = (hpack.max_packet_size + 7) / 8; 1957 1958 /* if report id is used, add more more byte for it */ 1959 if (hpack.report_id != HID_REPORT_ID_UNDEFINED) { 1960 hidp->hid_packet_size++; 1961 } 1962 } else { 1963 USB_DPRINTF_L1(PRINT_MASK_ATTA, hidp->hid_log_handle, 1964 "Invalid Report Descriptor"); 1965 freemsg(data); 1966 1967 return (USB_FAILURE); 1968 } 1969 1970 freemsg(data); 1971 1972 return (USB_SUCCESS); 1973 } 1974 } 1975 1976 1977 /* 1978 * hid_set_idle: 1979 * Make a clas specific request to SET_IDLE. 1980 * In this case send no reports if state has not changed. 1981 * See HID 7.2.4. 1982 */ 1983 /*ARGSUSED*/ 1984 static void 1985 hid_set_idle(hid_state_t *hidp) 1986 { 1987 usb_cr_t completion_reason; 1988 usb_cb_flags_t cb_flags; 1989 usb_ctrl_setup_t setup = { 1990 USB_DEV_REQ_HOST_TO_DEV | /* bmRequestType */ 1991 USB_DEV_REQ_TYPE_CLASS | 1992 USB_DEV_REQ_RCPT_IF, 1993 SET_IDLE, /* bRequest */ 1994 DURATION, /* wValue */ 1995 0, /* wIndex: interface, fill in later */ 1996 0, /* wLength */ 1997 0 /* attributes */ 1998 }; 1999 2000 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2001 "hid_set_idle: Begin"); 2002 2003 setup.wIndex = hidp->hid_if_descr.bInterfaceNumber; 2004 if (usb_pipe_ctrl_xfer_wait( 2005 hidp->hid_default_pipe, 2006 &setup, 2007 NULL, /* no data to send. */ 2008 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 2009 2010 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 2011 "Failed while trying to set idle," 2012 "cr = %d, cb_flags = 0x%x\n", 2013 completion_reason, cb_flags); 2014 } 2015 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2016 "hid_set_idle: End"); 2017 } 2018 2019 2020 /* 2021 * hid_set_protocol: 2022 * Initialize the device to set the preferred protocol 2023 */ 2024 /*ARGSUSED*/ 2025 static void 2026 hid_set_protocol(hid_state_t *hidp, int protocol) 2027 { 2028 usb_cr_t completion_reason; 2029 usb_cb_flags_t cb_flags; 2030 usb_ctrl_setup_t setup; 2031 2032 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2033 "hid_set_protocol(%d): Begin", protocol); 2034 2035 /* initialize the setup request */ 2036 setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV | 2037 USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; 2038 setup.bRequest = SET_PROTOCOL; 2039 setup.wValue = (uint16_t)protocol; 2040 setup.wIndex = hidp->hid_if_descr.bInterfaceNumber; 2041 setup.wLength = 0; 2042 setup.attrs = 0; 2043 if (usb_pipe_ctrl_xfer_wait( 2044 hidp->hid_default_pipe, /* bmRequestType */ 2045 &setup, 2046 NULL, /* no data to send */ 2047 &completion_reason, &cb_flags, 0) != USB_SUCCESS) { 2048 /* 2049 * Some devices fail to follow the specification 2050 * and instead of STALLing, they continously 2051 * NAK the SET_IDLE command. We need to reset 2052 * the pipe then, so that ohci doesn't panic. 2053 */ 2054 USB_DPRINTF_L2(PRINT_MASK_ATTA, hidp->hid_log_handle, 2055 "Failed while trying to set protocol:%d," 2056 "cr = %d cb_flags = 0x%x\n", 2057 completion_reason, cb_flags, protocol); 2058 } 2059 2060 USB_DPRINTF_L4(PRINT_MASK_ATTA, hidp->hid_log_handle, 2061 "hid_set_protocol: End"); 2062 } 2063 2064 2065 /* 2066 * hid_detach_cleanup: 2067 * called by attach and detach for cleanup. 2068 */ 2069 static void 2070 hid_detach_cleanup(dev_info_t *dip, hid_state_t *hidp) 2071 { 2072 int flags = hidp->hid_attach_flags; 2073 int rval; 2074 hid_power_t *hidpm; 2075 2076 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2077 "hid_detach_cleanup: Begin"); 2078 2079 if ((hidp->hid_attach_flags & HID_LOCK_INIT) == 0) { 2080 2081 goto done; 2082 } 2083 2084 /* 2085 * Disable the event callbacks first, after this point, event 2086 * callbacks will never get called. Note we shouldn't hold 2087 * mutex while unregistering events because there may be a 2088 * competing event callback thread. Event callbacks are done 2089 * with ndi mutex held and this can cause a potential deadlock. 2090 */ 2091 usb_unregister_event_cbs(dip, &hid_events); 2092 2093 mutex_enter(&hidp->hid_mutex); 2094 2095 hidpm = hidp->hid_pm; 2096 2097 USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle, 2098 "hid_detach_cleanup: hidpm=0x%p", (void *)hidpm); 2099 2100 if (hidpm && (hidp->hid_dev_state != USB_DEV_DISCONNECTED)) { 2101 2102 mutex_exit(&hidp->hid_mutex); 2103 hid_pm_busy_component(hidp); 2104 if (hid_is_pm_enabled(dip) == USB_SUCCESS) { 2105 2106 if (hidpm->hid_wakeup_enabled) { 2107 2108 /* First bring the device to full power */ 2109 (void) pm_raise_power(dip, 0, 2110 USB_DEV_OS_FULL_PWR); 2111 2112 /* Disable remote wakeup */ 2113 rval = usb_handle_remote_wakeup(dip, 2114 USB_REMOTE_WAKEUP_DISABLE); 2115 2116 if (rval != DDI_SUCCESS) { 2117 USB_DPRINTF_L2(PRINT_MASK_ALL, 2118 hidp->hid_log_handle, 2119 "hid_detach_cleanup: " 2120 "disble remote wakeup failed, " 2121 "rval= %d", rval); 2122 } 2123 } 2124 2125 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF); 2126 } 2127 hid_pm_idle_component(hidp); 2128 mutex_enter(&hidp->hid_mutex); 2129 } 2130 2131 if (hidpm) { 2132 freemsg(hidpm->hid_pm_pwrup); 2133 kmem_free(hidpm, sizeof (hid_power_t)); 2134 hidp->hid_pm = NULL; 2135 } 2136 2137 mutex_exit(&hidp->hid_mutex); 2138 2139 if (hidp->hid_report_descr != NULL) { 2140 (void) hidparser_free_report_descriptor_handle( 2141 hidp->hid_report_descr); 2142 } 2143 2144 if (flags & HID_MINOR_NODES) { 2145 ddi_remove_minor_node(dip, NULL); 2146 } 2147 2148 mutex_destroy(&hidp->hid_mutex); 2149 2150 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2151 "hid_detach_cleanup: End"); 2152 2153 done: 2154 usb_client_detach(dip, hidp->hid_dev_data); 2155 usb_free_log_hdl(hidp->hid_log_handle); 2156 ddi_soft_state_free(hid_statep, hidp->hid_instance); 2157 2158 ddi_prop_remove_all(dip); 2159 } 2160 2161 2162 /* 2163 * hid_start_intr_polling: 2164 * Allocate an interrupt request structure, initialize, 2165 * and start interrupt transfers. 2166 */ 2167 static int 2168 hid_start_intr_polling(hid_state_t *hidp) 2169 { 2170 usb_intr_req_t *req; 2171 int rval = USB_SUCCESS; 2172 2173 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2174 "hid_start_intr_polling: " 2175 "dev_state=%s internal_str_flag=%d external_str_flag=%d ph=0x%p", 2176 usb_str_dev_state(hidp->hid_dev_state), hidp->hid_internal_flag, 2177 hidp->hid_external_flag, (void *)hidp->hid_interrupt_pipe); 2178 2179 if (HID_IS_OPEN(hidp) && (hidp->hid_interrupt_pipe != NULL)) { 2180 /* 2181 * initialize interrupt pipe request structure 2182 */ 2183 req = usb_alloc_intr_req(hidp->hid_dip, 0, USB_FLAGS_SLEEP); 2184 req->intr_client_private = (usb_opaque_t)hidp; 2185 req->intr_attributes = USB_ATTRS_SHORT_XFER_OK | 2186 USB_ATTRS_AUTOCLEARING; 2187 req->intr_len = hidp->hid_packet_size; 2188 req->intr_cb = hid_interrupt_pipe_callback; 2189 req->intr_exc_cb = hid_interrupt_pipe_exception_callback; 2190 2191 /* 2192 * Start polling on the interrupt pipe. 2193 */ 2194 mutex_exit(&hidp->hid_mutex); 2195 2196 if ((rval = usb_pipe_intr_xfer(hidp->hid_interrupt_pipe, req, 2197 USB_FLAGS_SLEEP)) != USB_SUCCESS) { 2198 USB_DPRINTF_L2(PRINT_MASK_PM, hidp->hid_log_handle, 2199 "hid_start_intr_polling failed: rval = %d", 2200 rval); 2201 usb_free_intr_req(req); 2202 } 2203 2204 mutex_enter(&hidp->hid_mutex); 2205 } 2206 2207 USB_DPRINTF_L4(PRINT_MASK_PM, hidp->hid_log_handle, 2208 "hid_start_intr_polling: done, rval = %d", rval); 2209 2210 return (rval); 2211 } 2212 2213 2214 /* 2215 * hid_close_intr_pipe: 2216 * close the interrupt pipe after draining all callbacks 2217 */ 2218 static void 2219 hid_close_intr_pipe(hid_state_t *hidp) 2220 { 2221 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 2222 "hid_close_intr_pipe: Begin"); 2223 2224 if (hidp->hid_interrupt_pipe) { 2225 /* 2226 * Close the interrupt pipe 2227 */ 2228 mutex_exit(&hidp->hid_mutex); 2229 usb_pipe_close(hidp->hid_dip, hidp->hid_interrupt_pipe, 2230 USB_FLAGS_SLEEP, NULL, NULL); 2231 mutex_enter(&hidp->hid_mutex); 2232 hidp->hid_interrupt_pipe = NULL; 2233 } 2234 USB_DPRINTF_L4(PRINT_MASK_CLOSE, hidp->hid_log_handle, 2235 "hid_close_intr_pipe: End"); 2236 } 2237 2238 2239 /* 2240 * hid_mctl_receive: 2241 * Handle M_CTL messages from upper stream. If 2242 * we don't understand the command, free message. 2243 */ 2244 static int 2245 hid_mctl_receive(register queue_t *q, register mblk_t *mp) 2246 { 2247 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 2248 struct iocblk *iocp; 2249 int error = HID_FAILURE; 2250 uchar_t request_type; 2251 hid_req_t *hid_req_data = NULL; 2252 hid_polled_input_callback_t hid_polled_input; 2253 hid_vid_pid_t hid_vid_pid; 2254 2255 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2256 "hid_mctl_receive"); 2257 2258 iocp = (struct iocblk *)mp->b_rptr; 2259 2260 switch (iocp->ioc_cmd) { 2261 case HID_SET_REPORT: 2262 /* FALLTHRU */ 2263 case HID_SET_IDLE: 2264 /* FALLTHRU */ 2265 case HID_SET_PROTOCOL: 2266 request_type = USB_DEV_REQ_HOST_TO_DEV | 2267 USB_DEV_REQ_RCPT_IF | USB_DEV_REQ_TYPE_CLASS; 2268 2269 break; 2270 case HID_GET_REPORT: 2271 /* FALLTHRU */ 2272 case HID_GET_IDLE: 2273 /* FALLTHRU */ 2274 case HID_GET_PROTOCOL: 2275 request_type = USB_DEV_REQ_DEV_TO_HOST | 2276 USB_DEV_REQ_RCPT_IF | USB_DEV_REQ_TYPE_CLASS; 2277 2278 break; 2279 case HID_GET_PARSER_HANDLE: 2280 if (canputnext(RD(q))) { 2281 freemsg(mp->b_cont); 2282 mp->b_cont = hid_data2mblk( 2283 (uchar_t *)&hidp->hid_report_descr, 2284 sizeof (hidp->hid_report_descr)); 2285 if (mp->b_cont == NULL) { 2286 /* 2287 * can't allocate mblk, indicate 2288 * that nothing is returned 2289 */ 2290 iocp->ioc_count = 0; 2291 } else { 2292 iocp->ioc_count = 2293 sizeof (hidp->hid_report_descr); 2294 } 2295 qreply(q, mp); 2296 2297 return (HID_SUCCESS); 2298 } else { 2299 2300 /* retry */ 2301 return (HID_ENQUEUE); 2302 } 2303 case HID_GET_VID_PID: 2304 if (canputnext(RD(q))) { 2305 freemsg(mp->b_cont); 2306 2307 hid_vid_pid.VendorId = 2308 hidp->hid_dev_descr->idVendor; 2309 hid_vid_pid.ProductId = 2310 hidp->hid_dev_descr->idProduct; 2311 2312 mp->b_cont = hid_data2mblk( 2313 (uchar_t *)&hid_vid_pid, sizeof (hid_vid_pid_t)); 2314 if (mp->b_cont == NULL) { 2315 /* 2316 * can't allocate mblk, indicate that nothing 2317 * is being returned. 2318 */ 2319 iocp->ioc_count = 0; 2320 } else { 2321 iocp->ioc_count = 2322 sizeof (hid_vid_pid_t); 2323 } 2324 qreply(q, mp); 2325 2326 return (HID_SUCCESS); 2327 } else { 2328 2329 /* retry */ 2330 return (HID_ENQUEUE); 2331 } 2332 case HID_OPEN_POLLED_INPUT: 2333 if (canputnext(RD(q))) { 2334 freemsg(mp->b_cont); 2335 2336 /* Initialize the structure */ 2337 hid_polled_input.hid_polled_version = 2338 HID_POLLED_INPUT_V0; 2339 hid_polled_input.hid_polled_read = hid_polled_read; 2340 hid_polled_input.hid_polled_input_enter = 2341 hid_polled_input_enter; 2342 hid_polled_input.hid_polled_input_exit = 2343 hid_polled_input_exit; 2344 hid_polled_input.hid_polled_input_handle = 2345 (hid_polled_handle_t)hidp; 2346 2347 mp->b_cont = hid_data2mblk( 2348 (uchar_t *)&hid_polled_input, 2349 sizeof (hid_polled_input_callback_t)); 2350 if (mp->b_cont == NULL) { 2351 /* 2352 * can't allocate mblk, indicate that nothing 2353 * is being returned. 2354 */ 2355 iocp->ioc_count = 0; 2356 } else { 2357 /* Call down into USBA */ 2358 (void) hid_polled_input_init(hidp); 2359 2360 iocp->ioc_count = 2361 sizeof (hid_polled_input_callback_t); 2362 } 2363 qreply(q, mp); 2364 2365 return (HID_SUCCESS); 2366 } else { 2367 2368 /* retry */ 2369 return (HID_ENQUEUE); 2370 } 2371 case HID_CLOSE_POLLED_INPUT: 2372 /* Call down into USBA */ 2373 (void) hid_polled_input_fini(hidp); 2374 2375 iocp->ioc_count = 0; 2376 qreply(q, mp); 2377 2378 return (HID_SUCCESS); 2379 default: 2380 hid_qreply_merror(q, mp, EINVAL); 2381 2382 return (HID_FAILURE); 2383 } 2384 2385 /* 2386 * These (device executable) commands require a hid_req_t. 2387 * Make sure one is present 2388 */ 2389 if (mp->b_cont == NULL) { 2390 hid_qreply_merror(q, mp, EINVAL); 2391 2392 return (error); 2393 } else { 2394 hid_req_data = (hid_req_t *)mp->b_cont->b_rptr; 2395 if ((iocp->ioc_cmd == HID_SET_REPORT) && 2396 (hid_req_data->hid_req_wLength == 0)) { 2397 hid_qreply_merror(q, mp, EINVAL); 2398 2399 return (error); 2400 } 2401 } 2402 2403 /* 2404 * Check is version no. is correct. This 2405 * is coming from the user 2406 */ 2407 if (hid_req_data->hid_req_version_no != HID_VERSION_V_0) { 2408 hid_qreply_merror(q, mp, EINVAL); 2409 2410 return (error); 2411 } 2412 2413 mutex_enter(&hidp->hid_mutex); 2414 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2415 "hid_mctl_receive: dev_state=%s", 2416 usb_str_dev_state(hidp->hid_dev_state)); 2417 2418 switch (hidp->hid_dev_state) { 2419 case USB_DEV_PWRED_DOWN: 2420 /* 2421 * get the device full powered. We get a callback 2422 * which enables the WQ and kicks off IO 2423 */ 2424 hidp->hid_dev_state = USB_DEV_HID_POWER_CHANGE; 2425 mutex_exit(&hidp->hid_mutex); 2426 if (usb_req_raise_power(hidp->hid_dip, 0, 2427 USB_DEV_OS_FULL_PWR, hid_power_change_callback, 2428 hidp, 0) != USB_SUCCESS) { 2429 /* we retry raising power in wsrv */ 2430 mutex_enter(&hidp->hid_mutex); 2431 hidp->hid_dev_state = USB_DEV_PWRED_DOWN; 2432 mutex_exit(&hidp->hid_mutex); 2433 } 2434 error = HID_ENQUEUE; 2435 2436 break; 2437 case USB_DEV_HID_POWER_CHANGE: 2438 mutex_exit(&hidp->hid_mutex); 2439 error = HID_ENQUEUE; 2440 2441 break; 2442 case USB_DEV_ONLINE: 2443 if (HID_STREAMS_FLAG(q, hidp) != HID_STREAMS_DISMANTLING) { 2444 /* Send a message down */ 2445 mutex_exit(&hidp->hid_mutex); 2446 error = hid_mctl_execute_cmd(q, request_type, 2447 hid_req_data, mp); 2448 if (error == HID_FAILURE) { 2449 hid_qreply_merror(q, mp, EIO); 2450 } 2451 } else { 2452 mutex_exit(&hidp->hid_mutex); 2453 hid_qreply_merror(q, mp, EIO); 2454 } 2455 2456 break; 2457 default: 2458 mutex_exit(&hidp->hid_mutex); 2459 hid_qreply_merror(q, mp, EIO); 2460 2461 break; 2462 } 2463 2464 return (error); 2465 } 2466 2467 2468 /* 2469 * hid_mctl_execute_cmd: 2470 * Send the command to the device. 2471 */ 2472 static int 2473 hid_mctl_execute_cmd(queue_t *q, int request_type, hid_req_t *hid_req_data, 2474 mblk_t *mp) 2475 { 2476 int request_index; 2477 struct iocblk *iocp; 2478 hid_default_pipe_arg_t *def_pipe_arg; 2479 hid_state_t *hidp = (hid_state_t *)q->q_ptr; 2480 2481 iocp = (struct iocblk *)mp->b_rptr; 2482 USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle, 2483 "hid_mctl_execute_cmd: iocp=0x%p", (void *)iocp); 2484 2485 request_index = hidp->hid_if_descr.bInterfaceNumber; 2486 2487 /* 2488 * Set up the argument to be passed back to hid 2489 * when the asynchronous control callback is 2490 * executed. 2491 */ 2492 def_pipe_arg = kmem_zalloc(sizeof (hid_default_pipe_arg_t), 0); 2493 2494 if (def_pipe_arg == NULL) { 2495 2496 return (HID_FAILURE); 2497 } 2498 2499 def_pipe_arg->hid_default_pipe_arg_queue = q; 2500 def_pipe_arg->hid_default_pipe_arg_mctlmsg.ioc_cmd = iocp->ioc_cmd; 2501 def_pipe_arg->hid_default_pipe_arg_mctlmsg.ioc_count = 0; 2502 def_pipe_arg->hid_default_pipe_arg_mblk = mp; 2503 2504 /* 2505 * Send the command down to USBA through default 2506 * pipe. 2507 */ 2508 if (hid_send_async_ctrl_request(def_pipe_arg, hid_req_data, 2509 request_type, iocp->ioc_cmd, request_index) != USB_SUCCESS) { 2510 2511 kmem_free(def_pipe_arg, sizeof (hid_default_pipe_arg_t)); 2512 2513 return (HID_FAILURE); 2514 } 2515 2516 return (HID_INPROGRESS); 2517 } 2518 2519 2520 /* 2521 * hid_send_async_ctrl_request: 2522 * Send an asynchronous control request to USBA. Since hid is a STREAMS 2523 * driver, it is not allowed to wait in its entry points except for the 2524 * open and close entry points. Therefore, hid must use the asynchronous 2525 * USBA calls. 2526 */ 2527 static int 2528 hid_send_async_ctrl_request(hid_default_pipe_arg_t *hid_default_pipe_arg, 2529 hid_req_t *hid_request, 2530 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 }