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