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