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