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