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