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.
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.
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]
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Joyent, Inc.
29 * Human Interface Device driver (HID)
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
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).
40 * Undocumented functions may go away in a future Solaris OS release.
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.
47 #define USBDRV_MAJOR_VER 2
48 #define USBDRV_MINOR_VER 0
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>
63 extern int ddi_create_internal_pathname(dev_info_t
*, char *, int, minor_t
);
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;
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 */
74 /* soft state structures */
75 #define HID_INITIAL_SOFT_SPACE 4
76 static void *hid_statep
;
79 static void hid_interrupt_pipe_callback(usb_pipe_handle_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
,
84 static void hid_default_pipe_exception_callback(usb_pipe_handle_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
);
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
*);
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
*,
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
);
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
*);
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
*);
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
*);
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
*);
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
*);
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);
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.
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.
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
))
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 */
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 */
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 */
193 struct streamtab hid_streamtab
= {
196 NULL
, /* not a MUX */
200 struct cb_ops hid_cb_ops
= {
203 nulldev
, /* strategy */
209 nulldev
, /* devmap */
211 nulldev
, /* segmap */
213 ddi_prop_op
, /* cb_prop_op */
214 &hid_streamtab
, /* streamtab */
219 static struct dev_ops hid_ops
= {
220 DEVO_REV
, /* devo_rev, */
223 nulldev
, /* identify */
225 hid_attach
, /* attach */
226 hid_detach
, /* detach */
228 &hid_cb_ops
, /* driver operations */
229 NULL
, /* bus operations */
230 hid_power
, /* power */
231 ddi_quiesce_not_needed
, /* quiesce */
234 static struct modldrv hidmodldrv
= {
236 "USB HID Client Driver",
237 &hid_ops
/* driver ops */
240 static struct modlinkage modlinkage
= {
246 static usb_event_t hid_events
= {
247 hid_disconnect_event_callback
,
248 hid_restore_state_event_callback
,
259 if (((rval
= ddi_soft_state_init(&hid_statep
, sizeof (hid_state_t
),
260 HID_INITIAL_SOFT_SPACE
)) != 0)) {
265 if ((rval
= mod_install(&modlinkage
)) != 0) {
266 ddi_soft_state_fini(&hid_statep
);
278 if ((rval
= mod_remove(&modlinkage
)) != 0) {
283 ddi_soft_state_fini(&hid_statep
);
290 _info(struct modinfo
*modinfop
)
292 return (mod_info(&modlinkage
, modinfop
));
298 * Get minor number, soft state structure etc.
302 hid_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
, void **result
)
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
);
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
) {
319 case DDI_INFO_DEVT2INSTANCE
:
320 *result
= (void *)(uintptr_t)instance
;
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
340 hid_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
343 int instance
= ddi_get_instance(dip
);
344 int parse_hid_descr_error
= 0;
345 hid_state_t
*hidp
= NULL
;
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
;
357 hidp
= ddi_get_soft_state(hid_statep
, instance
);
358 hid_cpr_resume(hidp
);
359 return (DDI_SUCCESS
);
362 return (DDI_FAILURE
);
366 * Allocate softstate information and get softstate pointer
368 if (ddi_soft_state_zalloc(hid_statep
, instance
) == DDI_SUCCESS
) {
369 hidp
= ddi_get_soft_state(hid_statep
, instance
);
376 hidp
->hid_log_handle
= usb_alloc_log_hdl(dip
, NULL
, &hid_errlevel
,
377 &hid_errmask
, &hid_instance_debug
, 0);
379 hidp
->hid_instance
= instance
;
383 * Register with USBA. Just retrieve interface descriptor
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");
392 if (usb_get_dev_data(dip
, &dev_data
, USB_PARSE_LVL_IF
, 0) !=
395 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
396 "hid_attach: usb_get_dev_data() failed");
401 /* initialize mutex */
402 mutex_init(&hidp
->hid_mutex
, NULL
, MUTEX_DRIVER
,
403 dev_data
->dev_iblock_cookie
);
405 hidp
->hid_attach_flags
|= HID_LOCK_INIT
;
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];
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
;
417 * Make sure that the bInterfaceProtocol only has meaning to
418 * Boot Interface Subclass.
420 if (hidp
->hid_if_descr
.bInterfaceSubClass
!= BOOT_INTERFACE
)
421 hidp
->hid_if_descr
.bInterfaceProtocol
= NONE_PROTOCOL
;
422 mutex_exit(&hidp
->hid_mutex
);
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
) {
428 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
429 "no interrupt IN endpoint found");
434 mutex_enter(&hidp
->hid_mutex
);
435 if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION
, dip
, ep_data
,
436 &hidp
->hid_ep_intr_xdescr
) != USB_SUCCESS
) {
437 mutex_exit(&hidp
->hid_mutex
);
443 * Attempt to find the hid descriptor, it could be after interface
444 * or after endpoint descriptors
446 if (hid_parse_hid_descr(&hidp
->hid_hid_descr
, USB_HID_DESCR_SIZE
,
447 altif_data
, ep_data
) != USB_HID_DESCR_SIZE
) {
449 * If parsing of hid descriptor failed and
450 * the device is a keyboard or mouse, use predefined
451 * length and packet size.
453 if (hid_parse_hid_descr_failure(hidp
) == USB_FAILURE
) {
454 mutex_exit(&hidp
->hid_mutex
);
460 * hid descriptor was bad but since
461 * the device is a keyboard or mouse,
462 * we will use the default length
465 parse_hid_descr_error
= HID_BAD_DESCR
;
467 /* Parse hid descriptor successful */
469 USB_DPRINTF_L3(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
470 "Hid descriptor:\n\t"
471 "bLength = 0x%x bDescriptorType = 0x%x "
473 "bCountryCode = 0x%x bNumDescriptors = 0x%x\n\t"
474 "bReportDescriptorType = 0x%x\n\t"
475 "wReportDescriptorLength = 0x%x",
476 hidp
->hid_hid_descr
.bLength
,
477 hidp
->hid_hid_descr
.bDescriptorType
,
478 hidp
->hid_hid_descr
.bcdHID
,
479 hidp
->hid_hid_descr
.bCountryCode
,
480 hidp
->hid_hid_descr
.bNumDescriptors
,
481 hidp
->hid_hid_descr
.bReportDescriptorType
,
482 hidp
->hid_hid_descr
.wReportDescriptorLength
);
486 * Save a copy of the default pipe for easy reference
488 hidp
->hid_default_pipe
= hidp
->hid_dev_data
->dev_default_ph
;
490 /* we copied the descriptors we need, free the dev_data */
491 usb_free_dev_data(dip
, dev_data
);
492 hidp
->hid_dev_data
= NULL
;
495 * Don't get the report descriptor if parsing hid descriptor earlier
496 * failed since device probably won't return valid report descriptor
497 * either. Though parsing of hid descriptor failed, we have reached
498 * this point because the device has been identified as a
499 * keyboard or a mouse successfully and the default packet
500 * size and layout(in case of keyboard only) will be used, so it
501 * is ok to go ahead even if parsing of hid descriptor failed and
502 * we will not try to get the report descriptor.
504 if (parse_hid_descr_error
!= HID_BAD_DESCR
) {
506 * Sun mouse rev 105 is a bit slow in responding to this
507 * request and requires multiple retries
512 * Get and parse the report descriptor.
513 * Set the packet size if parsing is successful.
514 * Note that we start retry at 1 to have a delay
515 * in the first iteration.
517 mutex_exit(&hidp
->hid_mutex
);
518 for (retry
= 1; retry
< HID_RETRY
; retry
++) {
519 if (hid_handle_report_descriptor(hidp
,
520 hidp
->hid_interfaceno
) == USB_SUCCESS
) {
523 delay(retry
* drv_usectohz(1000));
525 if (retry
>= HID_RETRY
) {
529 mutex_enter(&hidp
->hid_mutex
);
532 * If packet size is zero, but the device is identified
533 * as a mouse or a keyboard, use predefined packet
536 if (hidp
->hid_packet_size
== 0) {
537 if (hidp
->hid_if_descr
.bInterfaceProtocol
==
539 /* device is a keyboard */
540 hidp
->hid_packet_size
= USBKPSZ
;
542 hid_if_descr
.bInterfaceProtocol
==
544 /* device is a mouse */
545 hidp
->hid_packet_size
= USBMSSZ
;
547 USB_DPRINTF_L2(PRINT_MASK_ATTA
,
548 hidp
->hid_log_handle
,
549 "Failed to find hid packet size");
550 mutex_exit(&hidp
->hid_mutex
);
558 * initialize the pipe policy for the interrupt pipe.
560 hidp
->hid_intr_pipe_policy
.pp_max_async_reqs
= 1;
563 * Make a clas specific request to SET_IDLE
564 * In this case send no reports if state has not changed.
567 mutex_exit(&hidp
->hid_mutex
);
570 /* always initialize to report protocol */
571 hid_set_protocol(hidp
, SET_REPORT_PROTOCOL
);
572 mutex_enter(&hidp
->hid_mutex
);
575 * Create minor node based on information from the
578 switch (hidp
->hid_if_descr
.bInterfaceProtocol
) {
579 case KEYBOARD_PROTOCOL
:
580 (void) strcpy(minor_name
, "keyboard");
584 (void) strcpy(minor_name
, "mouse");
589 * If the report descriptor has the GD mouse collection in
590 * its multiple collection, create a minor node and support it.
591 * It is used on some advanced keyboard/mouse set.
593 if (hidparser_lookup_usage_collection(
594 hidp
->hid_report_descr
, HID_GENERIC_DESKTOP
,
595 HID_GD_MOUSE
) != HIDPARSER_FAILURE
) {
596 (void) strcpy(minor_name
, "mouse");
601 if (hidparser_get_top_level_collection_usage(
602 hidp
->hid_report_descr
, &usage_page
, &usage
) !=
604 switch (usage_page
) {
607 case HID_CONSUMER_CONTROL
:
608 (void) strcpy(minor_name
,
613 (void) sprintf(minor_name
,
614 "hid_%d_%d", usage_page
, usage
);
620 case HID_GENERIC_DESKTOP
:
623 (void) strcpy(minor_name
,
628 (void) strcpy(minor_name
,
632 case HID_GD_KEYBOARD
:
633 (void) strcpy(minor_name
,
638 (void) sprintf(minor_name
,
639 "hid_%d_%d", usage_page
, usage
);
646 (void) sprintf(minor_name
,
647 "hid_%d_%d", usage_page
, usage
);
652 USB_DPRINTF_L1(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
653 "hid_attach: Unsupported HID device");
654 mutex_exit(&hidp
->hid_mutex
);
662 mutex_exit(&hidp
->hid_mutex
);
664 if ((ddi_create_minor_node(dip
, minor_name
, S_IFCHR
,
665 HID_CONSTRUCT_EXTERNAL_MINOR(instance
),
666 DDI_PSEUDO
, 0)) != DDI_SUCCESS
) {
667 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
668 "hid_attach: Could not create minor node");
673 /* create internal path for virtual */
674 if (strcmp(minor_name
, "mouse") == 0) {
675 if (ddi_create_internal_pathname(dip
, "internal_mouse", S_IFCHR
,
676 HID_CONSTRUCT_INTERNAL_MINOR(instance
)) != DDI_SUCCESS
) {
682 if (strcmp(minor_name
, "keyboard") == 0) {
683 if (ddi_create_internal_pathname(dip
, "internal_keyboard",
684 S_IFCHR
, HID_CONSTRUCT_INTERNAL_MINOR(instance
)) !=
691 mutex_enter(&hidp
->hid_mutex
);
692 hidp
->hid_attach_flags
|= HID_MINOR_NODES
;
693 hidp
->hid_dev_state
= USB_DEV_ONLINE
;
694 mutex_exit(&hidp
->hid_mutex
);
696 /* register for all events */
697 if (usb_register_event_cbs(dip
, &hid_events
, 0) != USB_SUCCESS
) {
698 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
699 "usb_register_event_cbs failed");
704 /* now create components to power manage this device */
705 hid_create_pm_components(dip
, hidp
);
706 hid_pm_busy_component(hidp
);
707 (void) pm_raise_power(dip
, 0, USB_DEV_OS_FULL_PWR
);
708 hid_pm_idle_component(hidp
);
710 hidp
->hid_internal_rq
= hidp
->hid_external_rq
= NULL
;
711 hidp
->hid_internal_flag
= hidp
->hid_external_flag
= 0;
712 hidp
->hid_inuse_rq
= NULL
;
719 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
722 return (DDI_SUCCESS
);
726 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
728 hid_detach_cleanup(dip
, hidp
);
731 return (DDI_FAILURE
);
737 * Gets called at the time of detach.
740 hid_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
742 int instance
= ddi_get_instance(dip
);
744 int rval
= DDI_FAILURE
;
746 hidp
= ddi_get_soft_state(hid_statep
, instance
);
748 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
, "hid_detach");
753 * Undo what we did in client_attach, freeing resources
754 * and removing things we installed. The system
755 * framework guarantees we are not active with this devinfo
756 * node in any other entry points at this time.
758 hid_detach_cleanup(dip
, hidp
);
760 return (DDI_SUCCESS
);
762 rval
= hid_cpr_suspend(hidp
);
764 return (rval
== USB_SUCCESS
? DDI_SUCCESS
: DDI_FAILURE
);
774 * Open entry point: Opens the interrupt pipe. Sets up queues.
778 hid_open(queue_t
*q
, dev_t
*devp
, int flag
, int sflag
, cred_t
*credp
)
784 minor_t minor
= getminor(*devp
);
786 instance
= HID_MINOR_TO_INSTANCE(minor
);
788 hidp
= ddi_get_soft_state(hid_statep
, instance
);
794 USB_DPRINTF_L4(PRINT_MASK_OPEN
, hidp
->hid_log_handle
,
798 /* clone open NOT supported here */
802 if (!(flag
& FREAD
)) {
807 * This is a workaround:
808 * Currently, if we open an already disconnected device, and send
809 * a CONSOPENPOLL ioctl to it, the system will panic, please refer
810 * to the processing HID_OPEN_POLLED_INPUT ioctl in the routine
811 * hid_mctl_receive().
812 * The consconfig_dacf module need this interface to detect if the
813 * device is already disconnnected.
815 mutex_enter(&hidp
->hid_mutex
);
816 if (HID_IS_INTERNAL_OPEN(minor
) &&
817 (hidp
->hid_dev_state
== USB_DEV_DISCONNECTED
)) {
818 mutex_exit(&hidp
->hid_mutex
);
822 if (HID_IS_INTERNAL_OPEN(minor
) &&
823 (hidp
->hid_internal_rq
!= NULL
)) {
824 ASSERT(hidp
->hid_internal_rq
== q
);
826 mutex_exit(&hidp
->hid_mutex
);
830 if ((!HID_IS_INTERNAL_OPEN(minor
)) &&
831 (hidp
->hid_external_rq
!= NULL
)) {
832 ASSERT(hidp
->hid_external_rq
== q
);
834 mutex_exit(&hidp
->hid_mutex
);
838 mutex_exit(&hidp
->hid_mutex
);
843 mutex_enter(&hidp
->hid_mutex
);
844 if (hidp
->hid_inuse_rq
!= NULL
) {
845 /* Pipe has already been setup */
847 if (HID_IS_INTERNAL_OPEN(minor
)) {
848 hidp
->hid_internal_flag
= HID_STREAMS_OPEN
;
849 hidp
->hid_inuse_rq
= hidp
->hid_internal_rq
= q
;
851 hidp
->hid_external_flag
= HID_STREAMS_OPEN
;
852 hidp
->hid_inuse_rq
= hidp
->hid_external_rq
= q
;
855 mutex_exit(&hidp
->hid_mutex
);
862 /* Pipe only needs to be opened once */
863 hidp
->hid_interrupt_pipe
= NULL
;
864 no_of_ep
= hidp
->hid_if_descr
.bNumEndpoints
;
865 mutex_exit(&hidp
->hid_mutex
);
867 /* Check if interrupt endpoint exists */
869 /* Open the interrupt pipe */
870 if (usb_pipe_xopen(hidp
->hid_dip
,
871 &hidp
->hid_ep_intr_xdescr
,
872 &hidp
->hid_intr_pipe_policy
, USB_FLAGS_SLEEP
,
873 &hidp
->hid_interrupt_pipe
) !=
882 hid_pm_busy_component(hidp
);
883 (void) pm_raise_power(hidp
->hid_dip
, 0, USB_DEV_OS_FULL_PWR
);
885 mutex_enter(&hidp
->hid_mutex
);
886 if (HID_IS_INTERNAL_OPEN(minor
)) {
887 hidp
->hid_internal_flag
= HID_STREAMS_OPEN
;
888 hidp
->hid_inuse_rq
= hidp
->hid_internal_rq
= q
;
890 hidp
->hid_external_flag
= HID_STREAMS_OPEN
;
891 hidp
->hid_inuse_rq
= hidp
->hid_external_rq
= q
;
894 mutex_exit(&hidp
->hid_mutex
);
898 mutex_enter(&hidp
->hid_mutex
);
900 if ((rval
= hid_start_intr_polling(hidp
)) != USB_SUCCESS
) {
901 USB_DPRINTF_L2(PRINT_MASK_OPEN
, hidp
->hid_log_handle
,
902 "unable to start intr pipe polling. rval = %d", rval
);
904 if (HID_IS_INTERNAL_OPEN(minor
))
905 hidp
->hid_internal_flag
= HID_STREAMS_DISMANTLING
;
907 hidp
->hid_external_flag
= HID_STREAMS_DISMANTLING
;
908 mutex_exit(&hidp
->hid_mutex
);
910 usb_pipe_close(hidp
->hid_dip
, hidp
->hid_interrupt_pipe
,
911 USB_FLAGS_SLEEP
, NULL
, NULL
);
913 mutex_enter(&hidp
->hid_mutex
);
914 hidp
->hid_interrupt_pipe
= NULL
;
915 mutex_exit(&hidp
->hid_mutex
);
919 mutex_enter(&hidp
->hid_mutex
);
920 if (HID_IS_INTERNAL_OPEN(minor
)) {
921 hidp
->hid_internal_flag
= 0;
922 hidp
->hid_internal_rq
= NULL
;
923 if (hidp
->hid_external_flag
== HID_STREAMS_OPEN
)
924 hidp
->hid_inuse_rq
= hidp
->hid_external_rq
;
926 hidp
->hid_inuse_rq
= NULL
;
928 hidp
->hid_external_flag
= 0;
929 hidp
->hid_external_rq
= NULL
;
930 if (hidp
->hid_internal_flag
== HID_STREAMS_OPEN
)
931 hidp
->hid_inuse_rq
= hidp
->hid_internal_rq
;
933 hidp
->hid_inuse_rq
= NULL
;
935 mutex_exit(&hidp
->hid_mutex
);
940 hid_pm_idle_component(hidp
);
944 mutex_exit(&hidp
->hid_mutex
);
946 USB_DPRINTF_L4(PRINT_MASK_OPEN
, hidp
->hid_log_handle
, "hid_open: End");
949 * Keyboard and mouse is Power managed by device activity.
950 * All other devices go busy on open and idle on close.
952 switch (hidp
->hid_pm
->hid_pm_strategy
) {
953 case HID_PM_ACTIVITY
:
954 hid_pm_idle_component(hidp
);
972 hid_close(queue_t
*q
, int flag
, cred_t
*credp
)
974 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
978 USB_DPRINTF_L4(PRINT_MASK_CLOSE
, hidp
->hid_log_handle
, "hid_close:");
980 mutex_enter(&hidp
->hid_mutex
);
982 ASSERT((hidp
->hid_internal_rq
== q
) ||
983 (hidp
->hid_external_rq
== q
));
985 if (hidp
->hid_internal_rq
== q
)
986 hidp
->hid_internal_flag
= HID_STREAMS_DISMANTLING
;
988 hidp
->hid_external_flag
= HID_STREAMS_DISMANTLING
;
990 mutex_exit(&hidp
->hid_mutex
);
993 * In case there are any outstanding requests on
994 * the default pipe, wait forever for them to complete.
996 (void) usb_pipe_drain_reqs(hidp
->hid_dip
,
997 hidp
->hid_default_pipe
, 0, USB_FLAGS_SLEEP
, NULL
, 0);
999 mutex_enter(&hidp
->hid_mutex
);
1001 /* drain any M_CTLS on the WQ */
1002 while (mp
= getq(wq
)) {
1003 hid_qreply_merror(wq
, mp
, EIO
);
1004 mutex_exit(&hidp
->hid_mutex
);
1005 hid_pm_idle_component(hidp
);
1006 mutex_enter(&hidp
->hid_mutex
);
1008 mutex_exit(&hidp
->hid_mutex
);
1015 mutex_enter(&hidp
->hid_mutex
);
1017 if (hidp
->hid_internal_rq
== q
) {
1018 hidp
->hid_internal_rq
= NULL
;
1019 hidp
->hid_internal_flag
= 0;
1020 if (hidp
->hid_inuse_rq
== q
) {
1021 /* We are closing the active stream */
1022 if (hidp
->hid_external_flag
== HID_STREAMS_OPEN
)
1023 hidp
->hid_inuse_rq
= hidp
->hid_external_rq
;
1025 hidp
->hid_inuse_rq
= NULL
;
1028 hidp
->hid_external_rq
= NULL
;
1029 hidp
->hid_external_flag
= 0;
1030 if (hidp
->hid_inuse_rq
== q
) {
1031 /* We are closing the active stream */
1032 if (hidp
->hid_internal_flag
== HID_STREAMS_OPEN
)
1033 hidp
->hid_inuse_rq
= hidp
->hid_internal_rq
;
1035 hidp
->hid_inuse_rq
= NULL
;
1039 if (hidp
->hid_inuse_rq
!= NULL
) {
1040 mutex_exit(&hidp
->hid_mutex
);
1044 /* all queues are closed, close USB pipes */
1045 hid_close_intr_pipe(hidp
);
1046 mutex_exit(&hidp
->hid_mutex
);
1049 * Devices other than keyboard/mouse go idle on close.
1051 switch (hidp
->hid_pm
->hid_pm_strategy
) {
1052 case HID_PM_ACTIVITY
:
1056 hid_pm_idle_component(hidp
);
1060 USB_DPRINTF_L4(PRINT_MASK_CLOSE
, hidp
->hid_log_handle
,
1069 * write put routine for the hid module
1072 hid_wput(queue_t
*q
, mblk_t
*mp
)
1074 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
1075 int error
= USB_SUCCESS
;
1076 struct iocblk
*iocbp
;
1079 struct copyresp
*crp
;
1083 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1086 /* See if the upper module is passing the right thing */
1088 ASSERT(mp
->b_datap
!= NULL
);
1090 switch (mp
->b_datap
->db_type
) {
1091 case M_FLUSH
: /* Canonical flush handling */
1092 if (*mp
->b_rptr
& FLUSHW
) {
1093 flushq(q
, FLUSHDATA
);
1096 /* read queue not used so just send up */
1097 if (*mp
->b_rptr
& FLUSHR
) {
1098 *mp
->b_rptr
&= ~FLUSHW
;
1106 iocbp
= (struct iocblk
*)mp
->b_rptr
;
1108 /* Only accept transparent ioctls */
1109 if (iocbp
->ioc_count
!= TRANSPARENT
) {
1110 miocnak(q
, mp
, 0, EINVAL
);
1114 switch (iocbp
->ioc_cmd
) {
1115 case HIDIOCKMGDIRECT
:
1117 mutex_enter(&hidp
->hid_mutex
);
1118 ASSERT(hidp
->hid_inuse_rq
!= NULL
);
1119 mutex_exit(&hidp
->hid_mutex
);
1121 if ((datap
= allocb(sizeof (int), BPRI_MED
)) == NULL
) {
1122 miocnak(q
, mp
, 0, ENOMEM
);
1126 mutex_enter(&hidp
->hid_mutex
);
1127 if (hidp
->hid_inuse_rq
== hidp
->hid_internal_rq
) {
1128 *(int *)datap
->b_wptr
= 0;
1129 datap
->b_wptr
+= sizeof (int);
1131 ASSERT(hidp
->hid_inuse_rq
==
1132 hidp
->hid_external_rq
);
1133 *(int *)datap
->b_wptr
= 1;
1134 datap
->b_wptr
+= sizeof (int);
1136 mutex_exit(&hidp
->hid_mutex
);
1138 mcopyout(mp
, NULL
, sizeof (int), NULL
, datap
);
1142 case HIDIOCKMSDIRECT
:
1143 mcopyin(mp
, NULL
, sizeof (int), NULL
);
1148 miocnak(q
, mp
, 0, ENOTTY
);
1155 crp
= (void *)mp
->b_rptr
;
1157 if (crp
->cp_rval
!= 0) {
1158 miocnak(q
, mp
, 0, EIO
);
1162 switch (crp
->cp_cmd
) {
1163 case HIDIOCKMGDIRECT
:
1164 miocack(q
, mp
, 0, 0);
1167 case HIDIOCKMSDIRECT
:
1168 direction
= *(int *)mp
->b_cont
->b_rptr
;
1170 if ((direction
!= 0) && (direction
!= 1)) {
1171 miocnak(q
, mp
, 0, EINVAL
);
1175 mutex_enter(&hidp
->hid_mutex
);
1177 if (direction
== 0) {
1178 /* The internal stream is made active */
1179 flag
= hidp
->hid_internal_flag
;
1180 tmpq
= hidp
->hid_internal_rq
;
1182 /* The external stream is made active */
1183 flag
= hidp
->hid_external_flag
;
1184 tmpq
= hidp
->hid_external_rq
;
1187 if (flag
!= HID_STREAMS_OPEN
) {
1188 mutex_exit(&hidp
->hid_mutex
);
1189 miocnak(q
, mp
, 0, EIO
);
1193 hidp
->hid_inuse_rq
= tmpq
;
1195 mutex_exit(&hidp
->hid_mutex
);
1196 miocack(q
, mp
, 0, 0);
1200 miocnak(q
, mp
, 0, ENOTTY
);
1207 /* we are busy now */
1208 hid_pm_busy_component(hidp
);
1213 error
= hid_mctl_receive(q
, mp
);
1217 * put this mblk on the WQ for the wsrv to
1223 case HID_INPROGRESS
:
1224 /* request has been queued to the device */
1229 * returned by M_CTLS that are processed
1236 hid_pm_idle_component(hidp
);
1242 hid_qreply_merror(q
, mp
, EINVAL
);
1243 error
= USB_FAILURE
;
1247 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1250 return (DDI_SUCCESS
);
1256 * Write service routine for hid. When a message arrives through
1257 * hid_wput(), it is kept in write queue to be serviced later.
1260 hid_wsrv(queue_t
*q
)
1262 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
1266 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1269 mutex_enter(&hidp
->hid_mutex
);
1270 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1271 "hid_wsrv: dev_state: %s",
1272 usb_str_dev_state(hidp
->hid_dev_state
));
1275 * raise power if we are powered down. It is OK to block here since
1276 * we have a separate thread to process this STREAM
1278 if (hidp
->hid_dev_state
== USB_DEV_PWRED_DOWN
) {
1279 mutex_exit(&hidp
->hid_mutex
);
1280 (void) pm_raise_power(hidp
->hid_dip
, 0, USB_DEV_OS_FULL_PWR
);
1281 mutex_enter(&hidp
->hid_mutex
);
1285 * continue servicing all the M_CTL's till the queue is empty
1286 * or the device gets disconnected or till a hid_close()
1288 while ((hidp
->hid_dev_state
== USB_DEV_ONLINE
) &&
1289 (HID_STREAMS_FLAG(q
, hidp
) != HID_STREAMS_DISMANTLING
) &&
1290 ((mp
= getq(q
)) != NULL
)) {
1292 /* Send a message down */
1293 mutex_exit(&hidp
->hid_mutex
);
1294 error
= hid_mctl_receive(q
, mp
);
1297 /* put this mblk back on q to preserve order */
1298 (void) putbq(q
, mp
);
1301 case HID_INPROGRESS
:
1302 /* request has been queued to the device */
1308 hid_pm_idle_component(hidp
);
1312 mutex_enter(&hidp
->hid_mutex
);
1314 mutex_exit(&hidp
->hid_mutex
);
1315 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1318 return (DDI_SUCCESS
);
1327 hid_power(dev_info_t
*dip
, int comp
, int level
)
1329 int instance
= ddi_get_instance(dip
);
1334 hidp
= ddi_get_soft_state(hid_statep
, instance
);
1336 USB_DPRINTF_L3(PRINT_MASK_PM
, hidp
->hid_log_handle
, "hid_power:"
1337 " hid_state: comp=%d level=%d", comp
, level
);
1339 /* check if we are transitioning to a legal power level */
1340 mutex_enter(&hidp
->hid_mutex
);
1341 hidpm
= hidp
->hid_pm
;
1343 if (USB_DEV_PWRSTATE_OK(hidpm
->hid_pwr_states
, level
)) {
1345 USB_DPRINTF_L2(PRINT_MASK_PM
, hidp
->hid_log_handle
,
1346 "hid_power: illegal level=%d hid_pwr_states=%d",
1347 level
, hidpm
->hid_pwr_states
);
1349 mutex_exit(&hidp
->hid_mutex
);
1351 return (DDI_FAILURE
);
1355 case USB_DEV_OS_PWR_OFF
:
1356 retval
= hid_pwrlvl0(hidp
);
1358 case USB_DEV_OS_PWR_1
:
1359 retval
= hid_pwrlvl1(hidp
);
1361 case USB_DEV_OS_PWR_2
:
1362 retval
= hid_pwrlvl2(hidp
);
1364 case USB_DEV_OS_FULL_PWR
:
1365 retval
= hid_pwrlvl3(hidp
);
1368 retval
= USB_FAILURE
;
1372 mutex_exit(&hidp
->hid_mutex
);
1374 return ((retval
== USB_SUCCESS
) ? DDI_SUCCESS
: DDI_FAILURE
);
1379 * hid_interrupt_pipe_callback:
1380 * Callback function for the hid intr pipe. This function is called by
1381 * USBA when a buffer has been filled. This driver does not cook the data,
1382 * it just sends the message up.
1385 hid_interrupt_pipe_callback(usb_pipe_handle_t pipe
, usb_intr_req_t
*req
)
1387 hid_state_t
*hidp
= (hid_state_t
*)req
->intr_client_private
;
1390 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1391 "hid_interrupt_pipe_callback: ph = 0x%p req = 0x%p",
1392 (void *)pipe
, (void *)req
);
1394 hid_pm_busy_component(hidp
);
1396 mutex_enter(&hidp
->hid_mutex
);
1399 * If hid_close() is in progress, we shouldn't try accessing queue
1400 * Otherwise indicate that a putnext is going to happen, so
1401 * if close after this, that should wait for the putnext to finish.
1403 if (HID_STREAMS_FLAG(hidp
->hid_inuse_rq
, hidp
) ==
1406 * Check if data can be put to the next queue.
1408 if (!canputnext(hidp
->hid_inuse_rq
)) {
1409 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1410 "Buffer flushed when overflowed.");
1412 /* Flush the queue above */
1413 hid_flush(hidp
->hid_inuse_rq
);
1414 mutex_exit(&hidp
->hid_mutex
);
1416 q
= hidp
->hid_inuse_rq
;
1417 mutex_exit(&hidp
->hid_mutex
);
1419 /* Put data upstream */
1420 putnext(q
, req
->intr_data
);
1422 /* usb_free_intr_req should not free data */
1423 req
->intr_data
= NULL
;
1426 mutex_exit(&hidp
->hid_mutex
);
1429 /* free request and data */
1430 usb_free_intr_req(req
);
1431 hid_pm_idle_component(hidp
);
1436 * hid_default_pipe_callback :
1437 * Callback routine for the asynchronous control transfer
1438 * Called from hid_send_async_ctrl_request() where we open
1439 * the pipe in exclusive mode
1442 hid_default_pipe_callback(usb_pipe_handle_t pipe
, usb_ctrl_req_t
*req
)
1444 hid_default_pipe_arg_t
*hid_default_pipe_arg
=
1445 (hid_default_pipe_arg_t
*)req
->ctrl_client_private
;
1446 queue_t
*wq
= hid_default_pipe_arg
->hid_default_pipe_arg_queue
;
1447 queue_t
*rq
= RD(wq
);
1448 hid_state_t
*hidp
= (hid_state_t
*)rq
->q_ptr
;
1450 mblk_t
*data
= NULL
;
1452 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1453 "hid_default_pipe_callback: "
1454 "ph = 0x%p, req = 0x%p, data= 0x%p",
1455 (void *)pipe
, (void *)req
, (void *)data
);
1457 ASSERT((req
->ctrl_cb_flags
& USB_CB_INTR_CONTEXT
) == 0);
1459 if (req
->ctrl_data
) {
1460 data
= req
->ctrl_data
;
1461 req
->ctrl_data
= NULL
;
1465 * Free the b_cont of the original message that was sent down.
1467 mctl_mp
= hid_default_pipe_arg
->hid_default_pipe_arg_mblk
;
1468 freemsg(mctl_mp
->b_cont
);
1470 /* chain the mblk received to the original & send it up */
1471 mctl_mp
->b_cont
= data
;
1473 if (canputnext(rq
)) {
1474 putnext(rq
, mctl_mp
);
1476 freemsg(mctl_mp
); /* avoid leak */
1480 * Free the argument for the asynchronous callback
1482 kmem_free(hid_default_pipe_arg
, sizeof (hid_default_pipe_arg_t
));
1485 * Free the control pipe request structure.
1487 usb_free_ctrl_req(req
);
1489 mutex_enter(&hidp
->hid_mutex
);
1490 hidp
->hid_default_pipe_req
--;
1491 ASSERT(hidp
->hid_default_pipe_req
>= 0);
1492 mutex_exit(&hidp
->hid_mutex
);
1494 hid_pm_idle_component(hidp
);
1500 * hid_interrupt_pipe_exception_callback:
1501 * Exception callback routine for interrupt pipe. If there is any data,
1502 * destroy it. No threads are waiting for the exception callback.
1506 hid_interrupt_pipe_exception_callback(usb_pipe_handle_t pipe
,
1507 usb_intr_req_t
*req
)
1509 hid_state_t
*hidp
= (hid_state_t
*)req
->intr_client_private
;
1510 mblk_t
*data
= req
->intr_data
;
1511 usb_cb_flags_t flags
= req
->intr_cb_flags
;
1514 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1515 "hid_interrupt_pipe_exception_callback: "
1516 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x",
1517 req
->intr_completion_reason
, (void *)data
, req
->intr_cb_flags
);
1519 ASSERT((req
->intr_cb_flags
& USB_CB_INTR_CONTEXT
) == 0);
1521 if (((flags
& USB_CB_FUNCTIONAL_STALL
) != 0) &&
1522 ((flags
& USB_CB_STALL_CLEARED
) == 0)) {
1523 USB_DPRINTF_L2(PRINT_MASK_ALL
,
1524 hidp
->hid_log_handle
,
1525 "hid_interrupt_pipe_exception_callback: "
1526 "unable to clear stall. flags = 0x%x",
1527 req
->intr_cb_flags
);
1530 mutex_enter(&hidp
->hid_mutex
);
1532 switch (req
->intr_completion_reason
) {
1533 case USB_CR_STOPPED_POLLING
:
1534 case USB_CR_PIPE_CLOSING
:
1538 case USB_CR_PIPE_RESET
:
1539 case USB_CR_NO_RESOURCES
:
1540 if ((hidp
->hid_dev_state
== USB_DEV_ONLINE
) &&
1541 ((rval
= hid_start_intr_polling(hidp
)) !=
1543 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1544 "unable to restart interrupt poll. rval = %d",
1551 mutex_exit(&hidp
->hid_mutex
);
1553 usb_free_intr_req(req
);
1558 * hid_default_pipe_exception_callback:
1559 * Exception callback routine for default pipe.
1563 hid_default_pipe_exception_callback(usb_pipe_handle_t pipe
,
1564 usb_ctrl_req_t
*req
)
1566 hid_default_pipe_arg_t
*hid_default_pipe_arg
=
1567 (hid_default_pipe_arg_t
*)req
->ctrl_client_private
;
1568 queue_t
*wq
= hid_default_pipe_arg
->hid_default_pipe_arg_queue
;
1569 queue_t
*rq
= RD(wq
);
1570 hid_state_t
*hidp
= (hid_state_t
*)rq
->q_ptr
;
1571 usb_cr_t ctrl_completion_reason
= req
->ctrl_completion_reason
;
1572 mblk_t
*mp
, *data
= NULL
;
1574 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
1575 "hid_default_pipe_exception_callback: "
1576 "completion_reason = 0x%x, data = 0x%p, flag = 0x%x",
1577 ctrl_completion_reason
, (void *)data
, req
->ctrl_cb_flags
);
1579 ASSERT((req
->ctrl_cb_flags
& USB_CB_INTR_CONTEXT
) == 0);
1581 mp
= hid_default_pipe_arg
->hid_default_pipe_arg_mblk
;
1584 * Pass an error message up. Reuse existing mblk.
1586 if (canputnext(rq
)) {
1587 mp
->b_datap
->db_type
= M_ERROR
;
1588 mp
->b_rptr
= mp
->b_datap
->db_base
;
1589 mp
->b_wptr
= mp
->b_rptr
+ sizeof (char);
1596 kmem_free(hid_default_pipe_arg
, sizeof (hid_default_pipe_arg_t
));
1598 mutex_enter(&hidp
->hid_mutex
);
1599 hidp
->hid_default_pipe_req
--;
1600 ASSERT(hidp
->hid_default_pipe_req
>= 0);
1601 mutex_exit(&hidp
->hid_mutex
);
1604 usb_free_ctrl_req(req
);
1605 hid_pm_idle_component(hidp
);
1612 * hid_reconnect_event_callback:
1613 * the device was disconnected but this instance not detached, probably
1614 * because the device was busy
1616 * If the same device, continue with restoring state
1619 hid_restore_state_event_callback(dev_info_t
*dip
)
1621 hid_state_t
*hidp
= (hid_state_t
*)ddi_get_soft_state(hid_statep
,
1622 ddi_get_instance(dip
));
1624 ASSERT(hidp
!= NULL
);
1626 USB_DPRINTF_L3(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1627 "hid_restore_state_event_callback: dip=0x%p", (void *)dip
);
1629 hid_restore_device_state(dip
, hidp
);
1631 return (USB_SUCCESS
);
1637 * Fail suspend if we can't finish outstanding i/o activity.
1640 hid_cpr_suspend(hid_state_t
*hidp
)
1642 int rval
, prev_state
;
1643 int retval
= USB_FAILURE
;
1645 USB_DPRINTF_L4(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1646 "hid_cpr_suspend: dip=0x%p", (void *)hidp
->hid_dip
);
1648 mutex_enter(&hidp
->hid_mutex
);
1649 switch (hidp
->hid_dev_state
) {
1650 case USB_DEV_ONLINE
:
1651 case USB_DEV_PWRED_DOWN
:
1652 prev_state
= hidp
->hid_dev_state
;
1653 hidp
->hid_dev_state
= USB_DEV_SUSPENDED
;
1654 mutex_exit(&hidp
->hid_mutex
);
1656 /* drain all request outstanding on the default control pipe */
1657 rval
= usb_pipe_drain_reqs(hidp
->hid_dip
,
1658 hidp
->hid_default_pipe
, hid_default_pipe_drain_timeout
,
1659 USB_FLAGS_SLEEP
, NULL
, 0);
1661 /* fail checkpoint if we haven't finished the job yet */
1662 mutex_enter(&hidp
->hid_mutex
);
1663 if ((rval
!= USB_SUCCESS
) || (hidp
->hid_default_pipe_req
> 0)) {
1664 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1666 "device busy - can't checkpoint");
1668 /* fall back to previous state */
1669 hidp
->hid_dev_state
= prev_state
;
1671 retval
= USB_SUCCESS
;
1672 hid_save_device_state(hidp
);
1676 case USB_DEV_DISCONNECTED
:
1677 hidp
->hid_dev_state
= USB_DEV_SUSPENDED
;
1678 hid_save_device_state(hidp
);
1679 retval
= USB_SUCCESS
;
1681 case USB_DEV_SUSPENDED
:
1683 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1684 "hid_cpr_suspend: Illegal dev state: %d",
1685 hidp
->hid_dev_state
);
1689 mutex_exit(&hidp
->hid_mutex
);
1696 hid_cpr_resume(hid_state_t
*hidp
)
1698 USB_DPRINTF_L4(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1699 "hid_cpr_resume: dip=0x%p", (void *)hidp
->hid_dip
);
1701 hid_restore_device_state(hidp
->hid_dip
, hidp
);
1706 * hid_disconnect_event_callback:
1707 * The device has been disconnected. We either wait for
1708 * detach or a reconnect event. Close all pipes and timeouts.
1711 hid_disconnect_event_callback(dev_info_t
*dip
)
1716 hidp
= (hid_state_t
*)ddi_get_soft_state(hid_statep
,
1717 ddi_get_instance(dip
));
1718 ASSERT(hidp
!= NULL
);
1720 USB_DPRINTF_L4(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1721 "hid_disconnect_event_callback: dip=0x%p", (void *)dip
);
1723 mutex_enter(&hidp
->hid_mutex
);
1724 switch (hidp
->hid_dev_state
) {
1725 case USB_DEV_ONLINE
:
1726 case USB_DEV_PWRED_DOWN
:
1727 hidp
->hid_dev_state
= USB_DEV_DISCONNECTED
;
1728 if (HID_IS_OPEN(hidp
)) {
1730 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1731 "busy device has been disconnected");
1733 hid_save_device_state(hidp
);
1736 * Notify applications about device removal, this only
1737 * applies to an external (aka. physical) open. For an
1738 * internal open, consconfig_dacf closes the queue.
1740 if (hidp
->hid_external_flag
== HID_STREAMS_OPEN
) {
1741 queue_t
*q
= hidp
->hid_external_rq
;
1742 mutex_exit(&hidp
->hid_mutex
);
1743 mp
= allocb(sizeof (uchar_t
), BPRI_HI
);
1745 mp
->b_datap
->db_type
= M_ERROR
;
1746 mp
->b_rptr
= mp
->b_datap
->db_base
;
1747 mp
->b_wptr
= mp
->b_rptr
+ sizeof (char);
1748 *mp
->b_rptr
= ENODEV
;
1751 mutex_enter(&hidp
->hid_mutex
);
1755 case USB_DEV_SUSPENDED
:
1756 /* we remain suspended */
1760 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
1761 "hid_disconnect_event_callback: Illegal dev state: %d",
1762 hidp
->hid_dev_state
);
1766 mutex_exit(&hidp
->hid_mutex
);
1768 return (USB_SUCCESS
);
1773 * hid_power_change_callback:
1774 * Async callback function to notify pm_raise_power completion
1775 * after hid_power entry point is called.
1778 hid_power_change_callback(void *arg
, int rval
)
1783 hidp
= (hid_state_t
*)arg
;
1785 USB_DPRINTF_L4(PRINT_MASK_PM
, hidp
->hid_log_handle
,
1786 "hid_power_change_callback - rval: %d", rval
);
1788 mutex_enter(&hidp
->hid_mutex
);
1789 hidp
->hid_pm
->hid_raise_power
= B_FALSE
;
1791 if (hidp
->hid_dev_state
== USB_DEV_ONLINE
) {
1792 wq
= WR(hidp
->hid_inuse_rq
);
1793 mutex_exit(&hidp
->hid_mutex
);
1798 mutex_exit(&hidp
->hid_mutex
);
1804 * hid_parse_hid_descr:
1805 * Parse the hid descriptor, check after interface and after
1806 * endpoint descriptor
1809 hid_parse_hid_descr(usb_hid_descr_t
*ret_descr
, size_t ret_buf_len
,
1810 usb_alt_if_data_t
*altif_data
, usb_ep_data_t
*ep_data
)
1812 usb_cvs_data_t
*cvs
;
1815 for (which_cvs
= 0; which_cvs
< altif_data
->altif_n_cvs
; which_cvs
++) {
1816 cvs
= &altif_data
->altif_cvs
[which_cvs
];
1817 if (cvs
->cvs_buf
== NULL
) {
1820 if (cvs
->cvs_buf
[1] == USB_DESCR_TYPE_HID
) {
1821 return (usb_parse_data("ccscccs",
1822 cvs
->cvs_buf
, cvs
->cvs_buf_len
,
1824 (size_t)ret_buf_len
));
1828 /* now try after endpoint */
1829 for (which_cvs
= 0; which_cvs
< ep_data
->ep_n_cvs
; which_cvs
++) {
1830 cvs
= &ep_data
->ep_cvs
[which_cvs
];
1831 if (cvs
->cvs_buf
== NULL
) {
1834 if (cvs
->cvs_buf
[1] == USB_DESCR_TYPE_HID
) {
1835 return (usb_parse_data("ccscccs",
1836 cvs
->cvs_buf
, cvs
->cvs_buf_len
,
1838 (size_t)ret_buf_len
));
1842 return (USB_PARSE_ERROR
);
1847 * hid_parse_hid_descr_failure:
1848 * If parsing of hid descriptor failed and the device is
1849 * a keyboard or mouse, use predefined length and packet size.
1852 hid_parse_hid_descr_failure(hid_state_t
*hidp
)
1855 * Parsing hid descriptor failed, probably because the
1856 * device did not return a valid hid descriptor. Check to
1857 * see if this is a keyboard or mouse. If so, use the
1858 * predefined hid descriptor length and packet size.
1859 * Otherwise, detach and return failure.
1861 USB_DPRINTF_L1(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1862 "Parsing of hid descriptor failed");
1864 if (hidp
->hid_if_descr
.bInterfaceProtocol
== KEYBOARD_PROTOCOL
) {
1865 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1866 "Set hid descriptor length to predefined "
1867 "USB_KB_HID_DESCR_LENGTH for keyboard.");
1869 /* device is a keyboard */
1870 hidp
->hid_hid_descr
.wReportDescriptorLength
=
1871 USB_KB_HID_DESCR_LENGTH
;
1873 hidp
->hid_packet_size
= USBKPSZ
;
1875 } else if (hidp
->hid_if_descr
.bInterfaceProtocol
==
1877 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1878 "Set hid descriptor length to predefined "
1879 "USB_MS_HID_DESCR_LENGTH for mouse.");
1881 /* device is a mouse */
1882 hidp
->hid_hid_descr
.wReportDescriptorLength
=
1883 USB_MS_HID_DESCR_LENGTH
;
1885 hidp
->hid_packet_size
= USBMSSZ
;
1888 return (USB_FAILURE
);
1891 return (USB_SUCCESS
);
1896 * hid_handle_report_descriptor:
1897 * Get the report descriptor, call hidparser routine to parse
1898 * it and query the hidparser tree to get the packet size
1901 hid_handle_report_descriptor(hid_state_t
*hidp
, int interface
)
1903 usb_cr_t completion_reason
;
1904 usb_cb_flags_t cb_flags
;
1905 mblk_t
*data
= NULL
;
1906 hidparser_packet_info_t hpack
;
1908 usb_ctrl_setup_t setup
= {
1909 USB_DEV_REQ_DEV_TO_HOST
| /* bmRequestType */
1910 USB_DEV_REQ_RCPT_IF
,
1911 USB_REQ_GET_DESCR
, /* bRequest */
1912 USB_CLASS_DESCR_TYPE_REPORT
, /* wValue */
1913 0, /* wIndex: interface, fill in later */
1914 0, /* wLength, fill in later */
1919 * Parsing hid desciptor was successful earlier.
1920 * Get Report Descriptor
1922 setup
.wIndex
= (uint16_t)interface
;
1923 setup
.wLength
= hidp
->hid_hid_descr
.wReportDescriptorLength
;
1924 if (usb_pipe_ctrl_xfer_wait(hidp
->hid_default_pipe
,
1927 &completion_reason
, &cb_flags
, 0) != USB_SUCCESS
) {
1929 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1930 "Failed to receive the Report Descriptor");
1933 return (USB_FAILURE
);
1936 int n
= hidp
->hid_hid_descr
.wReportDescriptorLength
;
1940 /* Print the report descriptor */
1941 for (i
= 0; i
< n
; i
++) {
1942 USB_DPRINTF_L3(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1943 "Index = %d\tvalue =0x%x", i
,
1944 (int)(data
->b_rptr
[i
]));
1947 /* Get Report Descriptor was successful */
1948 if (hidparser_parse_report_descriptor(
1950 hidp
->hid_hid_descr
.wReportDescriptorLength
,
1951 &hidp
->hid_hid_descr
,
1952 &hidp
->hid_report_descr
) == HIDPARSER_SUCCESS
) {
1954 /* find max intr-in xfer length */
1955 hidparser_find_max_packet_size_from_report_descriptor(
1956 hidp
->hid_report_descr
, &hpack
);
1957 /* round up to the nearest byte */
1958 hidp
->hid_packet_size
= (hpack
.max_packet_size
+ 7) / 8;
1960 /* if report id is used, add more more byte for it */
1961 if (hpack
.report_id
!= HID_REPORT_ID_UNDEFINED
) {
1962 hidp
->hid_packet_size
++;
1965 USB_DPRINTF_L1(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
1966 "Invalid Report Descriptor");
1969 return (USB_FAILURE
);
1974 return (USB_SUCCESS
);
1981 * Make a clas specific request to SET_IDLE.
1982 * In this case send no reports if state has not changed.
1987 hid_set_idle(hid_state_t
*hidp
)
1989 usb_cr_t completion_reason
;
1990 usb_cb_flags_t cb_flags
;
1991 usb_ctrl_setup_t setup
= {
1992 USB_DEV_REQ_HOST_TO_DEV
| /* bmRequestType */
1993 USB_DEV_REQ_TYPE_CLASS
|
1994 USB_DEV_REQ_RCPT_IF
,
1995 SET_IDLE
, /* bRequest */
1996 DURATION
, /* wValue */
1997 0, /* wIndex: interface, fill in later */
2002 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2003 "hid_set_idle: Begin");
2005 setup
.wIndex
= hidp
->hid_if_descr
.bInterfaceNumber
;
2006 if (usb_pipe_ctrl_xfer_wait(
2007 hidp
->hid_default_pipe
,
2009 NULL
, /* no data to send. */
2010 &completion_reason
, &cb_flags
, 0) != USB_SUCCESS
) {
2012 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2013 "Failed while trying to set idle,"
2014 "cr = %d, cb_flags = 0x%x\n",
2015 completion_reason
, cb_flags
);
2017 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2018 "hid_set_idle: End");
2024 * Initialize the device to set the preferred protocol
2028 hid_set_protocol(hid_state_t
*hidp
, int protocol
)
2030 usb_cr_t completion_reason
;
2031 usb_cb_flags_t cb_flags
;
2032 usb_ctrl_setup_t setup
;
2034 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2035 "hid_set_protocol(%d): Begin", protocol
);
2037 /* initialize the setup request */
2038 setup
.bmRequestType
= USB_DEV_REQ_HOST_TO_DEV
|
2039 USB_DEV_REQ_TYPE_CLASS
| USB_DEV_REQ_RCPT_IF
;
2040 setup
.bRequest
= SET_PROTOCOL
;
2041 setup
.wValue
= (uint16_t)protocol
;
2042 setup
.wIndex
= hidp
->hid_if_descr
.bInterfaceNumber
;
2045 if (usb_pipe_ctrl_xfer_wait(
2046 hidp
->hid_default_pipe
, /* bmRequestType */
2048 NULL
, /* no data to send */
2049 &completion_reason
, &cb_flags
, 0) != USB_SUCCESS
) {
2051 * Some devices fail to follow the specification
2052 * and instead of STALLing, they continously
2053 * NAK the SET_IDLE command. We need to reset
2054 * the pipe then, so that ohci doesn't panic.
2056 USB_DPRINTF_L2(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2057 "Failed while trying to set protocol:%d,"
2058 "cr = %d cb_flags = 0x%x\n",
2059 completion_reason
, cb_flags
, protocol
);
2062 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2063 "hid_set_protocol: End");
2068 * hid_detach_cleanup:
2069 * called by attach and detach for cleanup.
2072 hid_detach_cleanup(dev_info_t
*dip
, hid_state_t
*hidp
)
2074 int flags
= hidp
->hid_attach_flags
;
2078 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2079 "hid_detach_cleanup: Begin");
2081 if ((hidp
->hid_attach_flags
& HID_LOCK_INIT
) == 0) {
2087 * Disable the event callbacks first, after this point, event
2088 * callbacks will never get called. Note we shouldn't hold
2089 * mutex while unregistering events because there may be a
2090 * competing event callback thread. Event callbacks are done
2091 * with ndi mutex held and this can cause a potential deadlock.
2093 usb_unregister_event_cbs(dip
, &hid_events
);
2095 mutex_enter(&hidp
->hid_mutex
);
2097 hidpm
= hidp
->hid_pm
;
2099 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2100 "hid_detach_cleanup: hidpm=0x%p", (void *)hidpm
);
2102 if (hidpm
&& (hidp
->hid_dev_state
!= USB_DEV_DISCONNECTED
)) {
2104 mutex_exit(&hidp
->hid_mutex
);
2105 hid_pm_busy_component(hidp
);
2106 if (hid_is_pm_enabled(dip
) == USB_SUCCESS
) {
2108 if (hidpm
->hid_wakeup_enabled
) {
2110 /* First bring the device to full power */
2111 (void) pm_raise_power(dip
, 0,
2112 USB_DEV_OS_FULL_PWR
);
2114 /* Disable remote wakeup */
2115 rval
= usb_handle_remote_wakeup(dip
,
2116 USB_REMOTE_WAKEUP_DISABLE
);
2118 if (rval
!= DDI_SUCCESS
) {
2119 USB_DPRINTF_L2(PRINT_MASK_ALL
,
2120 hidp
->hid_log_handle
,
2121 "hid_detach_cleanup: "
2122 "disble remote wakeup failed, "
2127 (void) pm_lower_power(dip
, 0, USB_DEV_OS_PWR_OFF
);
2129 hid_pm_idle_component(hidp
);
2130 mutex_enter(&hidp
->hid_mutex
);
2134 freemsg(hidpm
->hid_pm_pwrup
);
2135 kmem_free(hidpm
, sizeof (hid_power_t
));
2136 hidp
->hid_pm
= NULL
;
2139 mutex_exit(&hidp
->hid_mutex
);
2141 if (hidp
->hid_report_descr
!= NULL
) {
2142 (void) hidparser_free_report_descriptor_handle(
2143 hidp
->hid_report_descr
);
2146 if (flags
& HID_MINOR_NODES
) {
2147 ddi_remove_minor_node(dip
, NULL
);
2150 mutex_destroy(&hidp
->hid_mutex
);
2152 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2153 "hid_detach_cleanup: End");
2156 usb_client_detach(dip
, hidp
->hid_dev_data
);
2157 usb_free_log_hdl(hidp
->hid_log_handle
);
2158 ddi_soft_state_free(hid_statep
, hidp
->hid_instance
);
2160 ddi_prop_remove_all(dip
);
2165 * hid_start_intr_polling:
2166 * Allocate an interrupt request structure, initialize,
2167 * and start interrupt transfers.
2170 hid_start_intr_polling(hid_state_t
*hidp
)
2172 usb_intr_req_t
*req
;
2173 int rval
= USB_SUCCESS
;
2175 USB_DPRINTF_L4(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2176 "hid_start_intr_polling: "
2177 "dev_state=%s internal_str_flag=%d external_str_flag=%d ph=0x%p",
2178 usb_str_dev_state(hidp
->hid_dev_state
), hidp
->hid_internal_flag
,
2179 hidp
->hid_external_flag
, (void *)hidp
->hid_interrupt_pipe
);
2181 if (HID_IS_OPEN(hidp
) && (hidp
->hid_interrupt_pipe
!= NULL
)) {
2183 * initialize interrupt pipe request structure
2185 req
= usb_alloc_intr_req(hidp
->hid_dip
, 0, USB_FLAGS_SLEEP
);
2186 req
->intr_client_private
= (usb_opaque_t
)hidp
;
2187 req
->intr_attributes
= USB_ATTRS_SHORT_XFER_OK
|
2188 USB_ATTRS_AUTOCLEARING
;
2189 req
->intr_len
= hidp
->hid_packet_size
;
2190 req
->intr_cb
= hid_interrupt_pipe_callback
;
2191 req
->intr_exc_cb
= hid_interrupt_pipe_exception_callback
;
2194 * Start polling on the interrupt pipe.
2196 mutex_exit(&hidp
->hid_mutex
);
2198 if ((rval
= usb_pipe_intr_xfer(hidp
->hid_interrupt_pipe
, req
,
2199 USB_FLAGS_SLEEP
)) != USB_SUCCESS
) {
2200 USB_DPRINTF_L2(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2201 "hid_start_intr_polling failed: rval = %d",
2203 usb_free_intr_req(req
);
2206 mutex_enter(&hidp
->hid_mutex
);
2209 USB_DPRINTF_L4(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2210 "hid_start_intr_polling: done, rval = %d", rval
);
2217 * hid_close_intr_pipe:
2218 * close the interrupt pipe after draining all callbacks
2221 hid_close_intr_pipe(hid_state_t
*hidp
)
2223 USB_DPRINTF_L4(PRINT_MASK_CLOSE
, hidp
->hid_log_handle
,
2224 "hid_close_intr_pipe: Begin");
2226 if (hidp
->hid_interrupt_pipe
) {
2228 * Close the interrupt pipe
2230 mutex_exit(&hidp
->hid_mutex
);
2231 usb_pipe_close(hidp
->hid_dip
, hidp
->hid_interrupt_pipe
,
2232 USB_FLAGS_SLEEP
, NULL
, NULL
);
2233 mutex_enter(&hidp
->hid_mutex
);
2234 hidp
->hid_interrupt_pipe
= NULL
;
2236 USB_DPRINTF_L4(PRINT_MASK_CLOSE
, hidp
->hid_log_handle
,
2237 "hid_close_intr_pipe: End");
2243 * Handle M_CTL messages from upper stream. If
2244 * we don't understand the command, free message.
2247 hid_mctl_receive(register queue_t
*q
, register mblk_t
*mp
)
2249 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
2250 struct iocblk
*iocp
;
2251 int error
= HID_FAILURE
;
2252 uchar_t request_type
;
2253 hid_req_t
*hid_req_data
= NULL
;
2254 hid_polled_input_callback_t hid_polled_input
;
2255 hid_vid_pid_t hid_vid_pid
;
2257 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2258 "hid_mctl_receive");
2260 iocp
= (struct iocblk
*)mp
->b_rptr
;
2262 switch (iocp
->ioc_cmd
) {
2263 case HID_SET_REPORT
:
2267 case HID_SET_PROTOCOL
:
2268 request_type
= USB_DEV_REQ_HOST_TO_DEV
|
2269 USB_DEV_REQ_RCPT_IF
| USB_DEV_REQ_TYPE_CLASS
;
2272 case HID_GET_REPORT
:
2276 case HID_GET_PROTOCOL
:
2277 request_type
= USB_DEV_REQ_DEV_TO_HOST
|
2278 USB_DEV_REQ_RCPT_IF
| USB_DEV_REQ_TYPE_CLASS
;
2281 case HID_GET_PARSER_HANDLE
:
2282 if (canputnext(RD(q
))) {
2283 freemsg(mp
->b_cont
);
2284 mp
->b_cont
= hid_data2mblk(
2285 (uchar_t
*)&hidp
->hid_report_descr
,
2286 sizeof (hidp
->hid_report_descr
));
2287 if (mp
->b_cont
== NULL
) {
2289 * can't allocate mblk, indicate
2290 * that nothing is returned
2292 iocp
->ioc_count
= 0;
2295 sizeof (hidp
->hid_report_descr
);
2299 return (HID_SUCCESS
);
2303 return (HID_ENQUEUE
);
2305 case HID_GET_VID_PID
:
2306 if (canputnext(RD(q
))) {
2307 freemsg(mp
->b_cont
);
2309 hid_vid_pid
.VendorId
=
2310 hidp
->hid_dev_descr
->idVendor
;
2311 hid_vid_pid
.ProductId
=
2312 hidp
->hid_dev_descr
->idProduct
;
2314 mp
->b_cont
= hid_data2mblk(
2315 (uchar_t
*)&hid_vid_pid
, sizeof (hid_vid_pid_t
));
2316 if (mp
->b_cont
== NULL
) {
2318 * can't allocate mblk, indicate that nothing
2319 * is being returned.
2321 iocp
->ioc_count
= 0;
2324 sizeof (hid_vid_pid_t
);
2328 return (HID_SUCCESS
);
2332 return (HID_ENQUEUE
);
2334 case HID_OPEN_POLLED_INPUT
:
2335 if (canputnext(RD(q
))) {
2336 freemsg(mp
->b_cont
);
2338 /* Initialize the structure */
2339 hid_polled_input
.hid_polled_version
=
2340 HID_POLLED_INPUT_V0
;
2341 hid_polled_input
.hid_polled_read
= hid_polled_read
;
2342 hid_polled_input
.hid_polled_input_enter
=
2343 hid_polled_input_enter
;
2344 hid_polled_input
.hid_polled_input_exit
=
2345 hid_polled_input_exit
;
2346 hid_polled_input
.hid_polled_input_handle
=
2347 (hid_polled_handle_t
)hidp
;
2349 mp
->b_cont
= hid_data2mblk(
2350 (uchar_t
*)&hid_polled_input
,
2351 sizeof (hid_polled_input_callback_t
));
2352 if (mp
->b_cont
== NULL
) {
2354 * can't allocate mblk, indicate that nothing
2355 * is being returned.
2357 iocp
->ioc_count
= 0;
2359 /* Call down into USBA */
2360 (void) hid_polled_input_init(hidp
);
2363 sizeof (hid_polled_input_callback_t
);
2367 return (HID_SUCCESS
);
2371 return (HID_ENQUEUE
);
2373 case HID_CLOSE_POLLED_INPUT
:
2374 /* Call down into USBA */
2375 (void) hid_polled_input_fini(hidp
);
2377 iocp
->ioc_count
= 0;
2380 return (HID_SUCCESS
);
2382 hid_qreply_merror(q
, mp
, EINVAL
);
2384 return (HID_FAILURE
);
2388 * These (device executable) commands require a hid_req_t.
2389 * Make sure one is present
2391 if (mp
->b_cont
== NULL
) {
2392 hid_qreply_merror(q
, mp
, EINVAL
);
2396 hid_req_data
= (hid_req_t
*)mp
->b_cont
->b_rptr
;
2397 if ((iocp
->ioc_cmd
== HID_SET_REPORT
) &&
2398 (hid_req_data
->hid_req_wLength
== 0)) {
2399 hid_qreply_merror(q
, mp
, EINVAL
);
2406 * Check is version no. is correct. This
2407 * is coming from the user
2409 if (hid_req_data
->hid_req_version_no
!= HID_VERSION_V_0
) {
2410 hid_qreply_merror(q
, mp
, EINVAL
);
2415 mutex_enter(&hidp
->hid_mutex
);
2416 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2417 "hid_mctl_receive: dev_state=%s",
2418 usb_str_dev_state(hidp
->hid_dev_state
));
2420 switch (hidp
->hid_dev_state
) {
2421 case USB_DEV_PWRED_DOWN
:
2423 * get the device full powered. We get a callback
2424 * which enables the WQ and kicks off IO
2426 hidp
->hid_dev_state
= USB_DEV_HID_POWER_CHANGE
;
2427 mutex_exit(&hidp
->hid_mutex
);
2428 if (usb_req_raise_power(hidp
->hid_dip
, 0,
2429 USB_DEV_OS_FULL_PWR
, hid_power_change_callback
,
2430 hidp
, 0) != USB_SUCCESS
) {
2431 /* we retry raising power in wsrv */
2432 mutex_enter(&hidp
->hid_mutex
);
2433 hidp
->hid_dev_state
= USB_DEV_PWRED_DOWN
;
2434 mutex_exit(&hidp
->hid_mutex
);
2436 error
= HID_ENQUEUE
;
2439 case USB_DEV_HID_POWER_CHANGE
:
2440 mutex_exit(&hidp
->hid_mutex
);
2441 error
= HID_ENQUEUE
;
2444 case USB_DEV_ONLINE
:
2445 if (HID_STREAMS_FLAG(q
, hidp
) != HID_STREAMS_DISMANTLING
) {
2446 /* Send a message down */
2447 mutex_exit(&hidp
->hid_mutex
);
2448 error
= hid_mctl_execute_cmd(q
, request_type
,
2450 if (error
== HID_FAILURE
) {
2451 hid_qreply_merror(q
, mp
, EIO
);
2454 mutex_exit(&hidp
->hid_mutex
);
2455 hid_qreply_merror(q
, mp
, EIO
);
2460 mutex_exit(&hidp
->hid_mutex
);
2461 hid_qreply_merror(q
, mp
, EIO
);
2471 * hid_mctl_execute_cmd:
2472 * Send the command to the device.
2475 hid_mctl_execute_cmd(queue_t
*q
, int request_type
, hid_req_t
*hid_req_data
,
2479 struct iocblk
*iocp
;
2480 hid_default_pipe_arg_t
*def_pipe_arg
;
2481 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
2483 iocp
= (struct iocblk
*)mp
->b_rptr
;
2484 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2485 "hid_mctl_execute_cmd: iocp=0x%p", (void *)iocp
);
2487 request_index
= hidp
->hid_if_descr
.bInterfaceNumber
;
2490 * Set up the argument to be passed back to hid
2491 * when the asynchronous control callback is
2494 def_pipe_arg
= kmem_zalloc(sizeof (hid_default_pipe_arg_t
), 0);
2496 if (def_pipe_arg
== NULL
) {
2498 return (HID_FAILURE
);
2501 def_pipe_arg
->hid_default_pipe_arg_queue
= q
;
2502 def_pipe_arg
->hid_default_pipe_arg_mctlmsg
.ioc_cmd
= iocp
->ioc_cmd
;
2503 def_pipe_arg
->hid_default_pipe_arg_mctlmsg
.ioc_count
= 0;
2504 def_pipe_arg
->hid_default_pipe_arg_mblk
= mp
;
2507 * Send the command down to USBA through default
2510 if (hid_send_async_ctrl_request(def_pipe_arg
, hid_req_data
,
2511 request_type
, iocp
->ioc_cmd
, request_index
) != USB_SUCCESS
) {
2513 kmem_free(def_pipe_arg
, sizeof (hid_default_pipe_arg_t
));
2515 return (HID_FAILURE
);
2518 return (HID_INPROGRESS
);
2523 * hid_send_async_ctrl_request:
2524 * Send an asynchronous control request to USBA. Since hid is a STREAMS
2525 * driver, it is not allowed to wait in its entry points except for the
2526 * open and close entry points. Therefore, hid must use the asynchronous
2530 hid_send_async_ctrl_request(hid_default_pipe_arg_t
*hid_default_pipe_arg
,
2531 hid_req_t
*hid_request
, uchar_t request_type
, int request_request
,
2532 ushort_t request_index
)
2534 queue_t
*q
= hid_default_pipe_arg
->hid_default_pipe_arg_queue
;
2535 hid_state_t
*hidp
= (hid_state_t
*)q
->q_ptr
;
2536 usb_ctrl_req_t
*ctrl_req
;
2540 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2541 "hid_send_async_ctrl_request: "
2542 "rq_type=%d rq_rq=%d index=%d",
2543 request_type
, request_request
, request_index
);
2545 mutex_enter(&hidp
->hid_mutex
);
2546 hidp
->hid_default_pipe_req
++;
2547 mutex_exit(&hidp
->hid_mutex
);
2550 * Note that ctrl_req->ctrl_data should be allocated by usba
2551 * only for IN requests. OUT request(e.g SET_REPORT) can have a
2552 * non-zero wLength value but ctrl_data would be allocated by
2555 if (hid_request
->hid_req_wLength
>= MAX_REPORT_DATA
) {
2556 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2557 "hid_req_wLength is exceeded");
2558 return (USB_FAILURE
);
2560 if ((request_type
& USB_DEV_REQ_DIR_MASK
) == USB_DEV_REQ_DEV_TO_HOST
) {
2561 length
= hid_request
->hid_req_wLength
;
2564 if ((ctrl_req
= usb_alloc_ctrl_req(hidp
->hid_dip
, length
, 0)) == NULL
) {
2565 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2566 "unable to alloc ctrl req. async trans failed");
2567 mutex_enter(&hidp
->hid_mutex
);
2568 hidp
->hid_default_pipe_req
--;
2569 ASSERT(hidp
->hid_default_pipe_req
>= 0);
2570 mutex_exit(&hidp
->hid_mutex
);
2572 return (USB_FAILURE
);
2575 if ((request_type
& USB_DEV_REQ_DIR_MASK
) == USB_DEV_REQ_HOST_TO_DEV
) {
2576 ASSERT((length
== 0) && (ctrl_req
->ctrl_data
== NULL
));
2579 ctrl_req
->ctrl_bmRequestType
= request_type
;
2580 ctrl_req
->ctrl_bRequest
= (uint8_t)request_request
;
2581 ctrl_req
->ctrl_wValue
= hid_request
->hid_req_wValue
;
2582 ctrl_req
->ctrl_wIndex
= request_index
;
2583 ctrl_req
->ctrl_wLength
= hid_request
->hid_req_wLength
;
2584 /* host to device: create a msg from hid_req_data */
2585 if ((request_type
& USB_DEV_REQ_DIR_MASK
) == USB_DEV_REQ_HOST_TO_DEV
) {
2586 mblk_t
*pblk
= allocb(hid_request
->hid_req_wLength
, BPRI_HI
);
2588 usb_free_ctrl_req(ctrl_req
);
2589 return (USB_FAILURE
);
2591 bcopy(hid_request
->hid_req_data
, pblk
->b_wptr
,
2592 hid_request
->hid_req_wLength
);
2593 pblk
->b_wptr
+= hid_request
->hid_req_wLength
;
2594 ctrl_req
->ctrl_data
= pblk
;
2596 ctrl_req
->ctrl_attributes
= USB_ATTRS_AUTOCLEARING
;
2597 ctrl_req
->ctrl_client_private
= (usb_opaque_t
)hid_default_pipe_arg
;
2598 ctrl_req
->ctrl_cb
= hid_default_pipe_callback
;
2599 ctrl_req
->ctrl_exc_cb
= hid_default_pipe_exception_callback
;
2601 if ((rval
= usb_pipe_ctrl_xfer(hidp
->hid_default_pipe
,
2602 ctrl_req
, 0)) != USB_SUCCESS
) {
2603 mutex_enter(&hidp
->hid_mutex
);
2604 hidp
->hid_default_pipe_req
--;
2605 ASSERT(hidp
->hid_default_pipe_req
>= 0);
2606 mutex_exit(&hidp
->hid_mutex
);
2608 usb_free_ctrl_req(ctrl_req
);
2609 USB_DPRINTF_L2(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
2610 "usb_pipe_ctrl_xfer() failed. rval = %d", rval
);
2612 return (USB_FAILURE
);
2615 return (USB_SUCCESS
);
2619 * hid_create_pm_components:
2620 * Create the pm components required for power management.
2621 * For keyboard/mouse, the components is created only if the device
2622 * supports a remote wakeup.
2623 * For other hid devices they are created unconditionally.
2626 hid_create_pm_components(dev_info_t
*dip
, hid_state_t
*hidp
)
2631 USB_DPRINTF_L4(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2632 "hid_create_pm_components: Begin");
2634 /* Allocate the state structure */
2635 hidpm
= kmem_zalloc(sizeof (hid_power_t
), KM_SLEEP
);
2636 hidp
->hid_pm
= hidpm
;
2637 hidpm
->hid_state
= hidp
;
2638 hidpm
->hid_raise_power
= B_FALSE
;
2639 hidpm
->hid_pm_capabilities
= 0;
2640 hidpm
->hid_current_power
= USB_DEV_OS_FULL_PWR
;
2642 switch (hidp
->hid_if_descr
.bInterfaceProtocol
) {
2643 case KEYBOARD_PROTOCOL
:
2644 case MOUSE_PROTOCOL
:
2645 hidpm
->hid_pm_strategy
= HID_PM_ACTIVITY
;
2646 if ((hid_is_pm_enabled(dip
) == USB_SUCCESS
) &&
2647 (usb_handle_remote_wakeup(dip
, USB_REMOTE_WAKEUP_ENABLE
) ==
2650 USB_DPRINTF_L3(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2651 "hid_create_pm_components: Remote Wakeup Enabled");
2653 if (usb_create_pm_components(dip
, &pwr_states
) ==
2655 hidpm
->hid_wakeup_enabled
= 1;
2656 hidpm
->hid_pwr_states
= (uint8_t)pwr_states
;
2662 hidpm
->hid_pm_strategy
= HID_PM_OPEN_CLOSE
;
2663 if ((hid_is_pm_enabled(dip
) == USB_SUCCESS
) &&
2664 (usb_create_pm_components(dip
, &pwr_states
) ==
2666 hidpm
->hid_wakeup_enabled
= 0;
2667 hidpm
->hid_pwr_states
= (uint8_t)pwr_states
;
2673 USB_DPRINTF_L4(PRINT_MASK_PM
, hidp
->hid_log_handle
,
2674 "hid_create_pm_components: END");
2680 * Check if the device is pm enabled. Always enable
2681 * pm on the new SUN mouse
2684 hid_is_pm_enabled(dev_info_t
*dip
)
2686 hid_state_t
*hidp
= ddi_get_soft_state(hid_statep
,
2687 ddi_get_instance(dip
));
2689 if (strcmp(ddi_node_name(dip
), "mouse") == 0) {
2690 /* check for overrides first */
2692 (ddi_prop_exists(DDI_DEV_T_ANY
, dip
,
2693 (DDI_PROP_DONTPASS
| DDI_PROP_NOTPROM
),
2694 "hid-mouse-pm-enable") == 1)) {
2696 return (USB_SUCCESS
);
2700 * Always enable PM for 1.05 or greater SUN mouse
2701 * hidp->hid_dev_descr won't be NULL.
2703 if ((hidp
->hid_dev_descr
->idVendor
==
2704 HID_SUN_MOUSE_VENDOR_ID
) &&
2705 (hidp
->hid_dev_descr
->idProduct
==
2706 HID_SUN_MOUSE_PROD_ID
) &&
2707 (hidp
->hid_dev_descr
->bcdDevice
>=
2708 HID_SUN_MOUSE_BCDDEVICE
)) {
2710 return (USB_SUCCESS
);
2714 return (USB_SUCCESS
);
2717 return (USB_FAILURE
);
2722 * hid_save_device_state
2723 * Save the current device/driver state.
2726 hid_save_device_state(hid_state_t
*hidp
)
2728 struct iocblk
*mctlmsg
;
2732 USB_DPRINTF_L4(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
2733 "hid_save_device_state");
2735 if (!(HID_IS_OPEN(hidp
)))
2738 if (hidp
->hid_internal_flag
== HID_STREAMS_OPEN
) {
2740 * Send MCTLs up indicating that the device
2741 * will loose its state
2743 q
= hidp
->hid_internal_rq
;
2745 mutex_exit(&hidp
->hid_mutex
);
2746 if (canputnext(q
)) {
2747 mp
= allocb(sizeof (struct iocblk
), BPRI_HI
);
2749 mp
->b_datap
->db_type
= M_CTL
;
2750 mctlmsg
= (struct iocblk
*)
2751 mp
->b_datap
->db_base
;
2752 mctlmsg
->ioc_cmd
= HID_DISCONNECT_EVENT
;
2753 mctlmsg
->ioc_count
= 0;
2757 mutex_enter(&hidp
->hid_mutex
);
2760 if (hidp
->hid_external_flag
== HID_STREAMS_OPEN
) {
2762 * Send MCTLs up indicating that the device
2763 * will loose its state
2765 q
= hidp
->hid_external_rq
;
2767 mutex_exit(&hidp
->hid_mutex
);
2768 if (canputnext(q
)) {
2769 mp
= allocb(sizeof (struct iocblk
), BPRI_HI
);
2771 mp
->b_datap
->db_type
= M_CTL
;
2772 mctlmsg
= (struct iocblk
*)
2773 mp
->b_datap
->db_base
;
2774 mctlmsg
->ioc_cmd
= HID_DISCONNECT_EVENT
;
2775 mctlmsg
->ioc_count
= 0;
2779 mutex_enter(&hidp
->hid_mutex
);
2782 mutex_exit(&hidp
->hid_mutex
);
2783 /* stop polling on the intr pipe */
2784 usb_pipe_stop_intr_polling(hidp
->hid_interrupt_pipe
, USB_FLAGS_SLEEP
);
2785 mutex_enter(&hidp
->hid_mutex
);
2790 * hid_restore_device_state:
2791 * Set original configuration of the device.
2793 * Enable wrq - this starts new transactions on the control pipe.
2796 hid_restore_device_state(dev_info_t
*dip
, hid_state_t
*hidp
)
2800 struct iocblk
*mctlmsg
;
2804 hid_pm_busy_component(hidp
);
2805 mutex_enter(&hidp
->hid_mutex
);
2807 USB_DPRINTF_L4(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2808 "hid_restore_device_state: %s",
2809 usb_str_dev_state(hidp
->hid_dev_state
));
2811 hidpm
= hidp
->hid_pm
;
2812 mutex_exit(&hidp
->hid_mutex
);
2814 /* First bring the device to full power */
2815 (void) pm_raise_power(dip
, 0, USB_DEV_OS_FULL_PWR
);
2817 mutex_enter(&hidp
->hid_mutex
);
2818 if (hidp
->hid_dev_state
== USB_DEV_ONLINE
) {
2820 * We failed the checkpoint, there is no need to restore
2823 mutex_exit(&hidp
->hid_mutex
);
2824 hid_pm_idle_component(hidp
);
2828 mutex_exit(&hidp
->hid_mutex
);
2831 /* Check if we are talking to the same device */
2832 if (usb_check_same_device(dip
, hidp
->hid_log_handle
, USB_LOG_L2
,
2833 PRINT_MASK_ALL
, USB_CHK_BASIC
|USB_CHK_CFG
, NULL
) != USB_SUCCESS
) {
2835 /* change the device state from suspended to disconnected */
2836 mutex_enter(&hidp
->hid_mutex
);
2837 hidp
->hid_dev_state
= USB_DEV_DISCONNECTED
;
2838 mutex_exit(&hidp
->hid_mutex
);
2839 hid_pm_idle_component(hidp
);
2844 hid_set_protocol(hidp
, SET_REPORT_PROTOCOL
);
2846 mutex_enter(&hidp
->hid_mutex
);
2847 /* if the device had remote wakeup earlier, enable it again */
2848 if (hidpm
->hid_wakeup_enabled
) {
2849 mutex_exit(&hidp
->hid_mutex
);
2851 if ((rval
= usb_handle_remote_wakeup(hidp
->hid_dip
,
2852 USB_REMOTE_WAKEUP_ENABLE
)) != USB_SUCCESS
) {
2853 USB_DPRINTF_L2(PRINT_MASK_ATTA
,
2854 hidp
->hid_log_handle
,
2855 "usb_handle_remote_wakeup failed (%d)", rval
);
2858 mutex_enter(&hidp
->hid_mutex
);
2862 * restart polling on the interrupt pipe only if the device
2863 * was previously operational (open)
2865 if (HID_IS_OPEN(hidp
)) {
2866 if ((rval
= hid_start_intr_polling(hidp
)) != USB_SUCCESS
) {
2867 USB_DPRINTF_L3(PRINT_MASK_ATTA
, hidp
->hid_log_handle
,
2868 "hid_restore_device_state:"
2869 "unable to restart intr pipe poll"
2870 " rval = %d ", rval
);
2872 * change the device state from
2873 * suspended to disconnected
2875 hidp
->hid_dev_state
= USB_DEV_DISCONNECTED
;
2876 mutex_exit(&hidp
->hid_mutex
);
2877 hid_pm_idle_component(hidp
);
2881 if (hidp
->hid_dev_state
== USB_DEV_DISCONNECTED
) {
2882 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
2883 "device is being re-connected");
2886 /* set the device state ONLINE */
2887 hidp
->hid_dev_state
= USB_DEV_ONLINE
;
2889 /* inform upstream modules that the device is back */
2890 if (hidp
->hid_internal_flag
== HID_STREAMS_OPEN
) {
2891 q
= hidp
->hid_internal_rq
;
2893 mutex_exit(&hidp
->hid_mutex
);
2894 if (canputnext(q
)) {
2895 mp
= allocb(sizeof (struct iocblk
), BPRI_HI
);
2897 mp
->b_datap
->db_type
= M_CTL
;
2898 mctlmsg
= (struct iocblk
*)
2899 mp
->b_datap
->db_base
;
2900 mctlmsg
->ioc_cmd
= HID_CONNECT_EVENT
;
2901 mctlmsg
->ioc_count
= 0;
2905 /* enable write side q */
2907 mutex_enter(&hidp
->hid_mutex
);
2910 if (hidp
->hid_external_flag
== HID_STREAMS_OPEN
) {
2911 q
= hidp
->hid_external_rq
;
2913 mutex_exit(&hidp
->hid_mutex
);
2914 if (canputnext(q
)) {
2915 mp
= allocb(sizeof (struct iocblk
), BPRI_HI
);
2917 mp
->b_datap
->db_type
= M_CTL
;
2918 mctlmsg
= (struct iocblk
*)
2919 mp
->b_datap
->db_base
;
2920 mctlmsg
->ioc_cmd
= HID_CONNECT_EVENT
;
2921 mctlmsg
->ioc_count
= 0;
2925 /* enable write side q */
2927 mutex_enter(&hidp
->hid_mutex
);
2930 /* set the device state ONLINE */
2931 hidp
->hid_dev_state
= USB_DEV_ONLINE
;
2934 mutex_exit(&hidp
->hid_mutex
);
2935 hid_pm_idle_component(hidp
);
2940 * Notify applications about device removal. This only
2941 * applies to an external (aka. physical) open. Not sure how to
2942 * notify consconfig to close the internal minor node.
2944 mutex_enter(&hidp
->hid_mutex
);
2946 if ((q
= hidp
->hid_external_rq
) == NULL
) {
2947 mutex_exit(&hidp
->hid_mutex
);
2951 mutex_exit(&hidp
->hid_mutex
);
2952 mp
= allocb(sizeof (uchar_t
), BPRI_HI
);
2954 mp
->b_datap
->db_type
= M_ERROR
;
2955 mp
->b_rptr
= mp
->b_datap
->db_base
;
2956 mp
->b_wptr
= mp
->b_rptr
+ sizeof (char);
2957 *mp
->b_rptr
= ENODEV
;
2964 * hid_qreply_merror:
2965 * Pass an error message up.
2968 hid_qreply_merror(queue_t
*q
, mblk_t
*mp
, uchar_t errval
)
2970 mp
->b_datap
->db_type
= M_ERROR
;
2972 freemsg(mp
->b_cont
);
2975 mp
->b_rptr
= mp
->b_datap
->db_base
;
2976 mp
->b_wptr
= mp
->b_rptr
+ sizeof (char);
2977 *mp
->b_rptr
= errval
;
2985 * Form an mblk from the given data
2988 hid_data2mblk(uchar_t
*buf
, int len
)
2993 mp
= allocb(len
, BPRI_HI
);
2995 bcopy(buf
, mp
->b_datap
->db_base
, len
);
3006 * Flush data already sent upstreams to client module.
3009 hid_flush(queue_t
*q
)
3012 * Flush pending data already sent upstream
3014 if ((q
!= NULL
) && (q
->q_next
!= NULL
)) {
3015 (void) putnextctl1(q
, M_FLUSH
, FLUSHR
);
3021 hid_pm_busy_component(hid_state_t
*hid_statep
)
3023 ASSERT(!mutex_owned(&hid_statep
->hid_mutex
));
3025 if (hid_statep
->hid_pm
!= NULL
) {
3026 mutex_enter(&hid_statep
->hid_mutex
);
3027 hid_statep
->hid_pm
->hid_pm_busy
++;
3029 USB_DPRINTF_L4(PRINT_MASK_PM
, hid_statep
->hid_log_handle
,
3030 "hid_pm_busy_component: %d",
3031 hid_statep
->hid_pm
->hid_pm_busy
);
3033 mutex_exit(&hid_statep
->hid_mutex
);
3034 if (pm_busy_component(hid_statep
->hid_dip
, 0) != DDI_SUCCESS
) {
3035 mutex_enter(&hid_statep
->hid_mutex
);
3036 hid_statep
->hid_pm
->hid_pm_busy
--;
3038 USB_DPRINTF_L2(PRINT_MASK_PM
,
3039 hid_statep
->hid_log_handle
,
3040 "hid_pm_busy_component failed: %d",
3041 hid_statep
->hid_pm
->hid_pm_busy
);
3043 mutex_exit(&hid_statep
->hid_mutex
);
3051 hid_pm_idle_component(hid_state_t
*hid_statep
)
3053 ASSERT(!mutex_owned(&hid_statep
->hid_mutex
));
3055 if (hid_statep
->hid_pm
!= NULL
) {
3056 if (pm_idle_component(hid_statep
->hid_dip
, 0) == DDI_SUCCESS
) {
3057 mutex_enter(&hid_statep
->hid_mutex
);
3058 ASSERT(hid_statep
->hid_pm
->hid_pm_busy
> 0);
3059 hid_statep
->hid_pm
->hid_pm_busy
--;
3061 USB_DPRINTF_L4(PRINT_MASK_PM
,
3062 hid_statep
->hid_log_handle
,
3063 "hid_pm_idle_component: %d",
3064 hid_statep
->hid_pm
->hid_pm_busy
);
3066 mutex_exit(&hid_statep
->hid_mutex
);
3074 * Functions to handle power transition for various levels
3075 * These functions act as place holders to issue USB commands
3076 * to the devices to change their power levels
3079 hid_pwrlvl0(hid_state_t
*hidp
)
3083 struct iocblk
*mctlmsg
;
3084 mblk_t
*mp_lowpwr
, *mp_fullpwr
;
3087 hidpm
= hidp
->hid_pm
;
3089 switch (hidp
->hid_dev_state
) {
3090 case USB_DEV_ONLINE
:
3091 /* Deny the powerdown request if the device is busy */
3092 if (hidpm
->hid_pm_busy
!= 0) {
3094 return (USB_FAILURE
);
3097 if (HID_IS_OPEN(hidp
)) {
3098 q
= hidp
->hid_inuse_rq
;
3099 mutex_exit(&hidp
->hid_mutex
);
3100 if (canputnext(q
)) {
3101 /* try to preallocate mblks */
3103 (int)sizeof (struct iocblk
), BPRI_HI
);
3104 mp_fullpwr
= allocb(
3105 (int)sizeof (struct iocblk
), BPRI_HI
);
3106 if ((mp_lowpwr
!= NULL
) &&
3107 (mp_fullpwr
!= NULL
)) {
3109 usb_pipe_stop_intr_polling(
3110 hidp
->hid_interrupt_pipe
,
3114 * Send an MCTL up indicating that
3115 * we are powering off
3117 mp_lowpwr
->b_datap
->db_type
= M_CTL
;
3118 mctlmsg
= (struct iocblk
*)
3119 mp_lowpwr
->b_datap
->db_base
;
3120 mctlmsg
->ioc_cmd
= HID_POWER_OFF
;
3121 mctlmsg
->ioc_count
= 0;
3122 putnext(q
, mp_lowpwr
);
3124 /* save the full powr mblk */
3125 mutex_enter(&hidp
->hid_mutex
);
3126 hidpm
->hid_pm_pwrup
= mp_fullpwr
;
3129 * Since we failed to allocate one
3130 * or more mblks, we fail attempt
3131 * to go into low power this time
3134 freemsg(mp_fullpwr
);
3135 mutex_enter(&hidp
->hid_mutex
);
3137 return (USB_FAILURE
);
3141 * Since we can't send an mblk up,
3142 * we fail this attempt to go to low power
3144 mutex_enter(&hidp
->hid_mutex
);
3146 return (USB_FAILURE
);
3150 mutex_exit(&hidp
->hid_mutex
);
3151 /* Issue USB D3 command to the device here */
3152 rval
= usb_set_device_pwrlvl3(hidp
->hid_dip
);
3153 ASSERT(rval
== USB_SUCCESS
);
3155 mutex_enter(&hidp
->hid_mutex
);
3156 hidp
->hid_dev_state
= USB_DEV_PWRED_DOWN
;
3157 hidpm
->hid_current_power
= USB_DEV_OS_PWR_OFF
;
3160 case USB_DEV_DISCONNECTED
:
3161 case USB_DEV_SUSPENDED
:
3162 case USB_DEV_PWRED_DOWN
:
3167 return (USB_SUCCESS
);
3173 hid_pwrlvl1(hid_state_t
*hidp
)
3177 /* Issue USB D2 command to the device here */
3178 rval
= usb_set_device_pwrlvl2(hidp
->hid_dip
);
3179 ASSERT(rval
== USB_SUCCESS
);
3181 return (USB_FAILURE
);
3187 hid_pwrlvl2(hid_state_t
*hidp
)
3191 rval
= usb_set_device_pwrlvl1(hidp
->hid_dip
);
3192 ASSERT(rval
== USB_SUCCESS
);
3194 return (USB_FAILURE
);
3199 hid_pwrlvl3(hid_state_t
*hidp
)
3203 struct iocblk
*mctlmsg
;
3207 hidpm
= hidp
->hid_pm
;
3209 switch (hidp
->hid_dev_state
) {
3210 case USB_DEV_HID_POWER_CHANGE
:
3211 case USB_DEV_PWRED_DOWN
:
3212 /* Issue USB D0 command to the device here */
3213 rval
= usb_set_device_pwrlvl0(hidp
->hid_dip
);
3214 ASSERT(rval
== USB_SUCCESS
);
3216 if (HID_IS_OPEN(hidp
)) {
3217 /* restart polling on intr pipe */
3218 rval
= hid_start_intr_polling(hidp
);
3219 if (rval
!= USB_SUCCESS
) {
3220 USB_DPRINTF_L2(PRINT_MASK_EVENTS
,
3221 hidp
->hid_log_handle
,
3222 "unable to restart intr polling rval = %d",
3225 return (USB_FAILURE
);
3228 /* Send an MCTL up indicating device in full power */
3229 q
= hidp
->hid_inuse_rq
;
3230 mp
= hidpm
->hid_pm_pwrup
;
3231 hidpm
->hid_pm_pwrup
= NULL
;
3232 mutex_exit(&hidp
->hid_mutex
);
3233 if (canputnext(q
)) {
3234 mp
->b_datap
->db_type
= M_CTL
;
3235 mctlmsg
= (struct iocblk
*)
3236 mp
->b_datap
->db_base
;
3237 mctlmsg
->ioc_cmd
= HID_FULL_POWER
;
3238 mctlmsg
->ioc_count
= 0;
3243 mutex_enter(&hidp
->hid_mutex
);
3246 hidp
->hid_dev_state
= USB_DEV_ONLINE
;
3247 hidpm
->hid_current_power
= USB_DEV_OS_FULL_PWR
;
3250 case USB_DEV_DISCONNECTED
:
3251 case USB_DEV_SUSPENDED
:
3252 case USB_DEV_ONLINE
:
3254 return (USB_SUCCESS
);
3256 USB_DPRINTF_L2(PRINT_MASK_EVENTS
, hidp
->hid_log_handle
,
3257 "hid_pwrlvl3: Improper State");
3259 return (USB_FAILURE
);
3265 * hid_polled_input_init :
3266 * This routine calls down to the lower layers to initialize any state
3267 * information. This routine initializes the lower layers for input.
3270 hid_polled_input_init(hid_state_t
*hidp
)
3272 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
3273 "hid_polled_input_init");
3276 * Call the lower layers to intialize any state information
3277 * that they will need to provide the polled characters.
3279 if (usb_console_input_init(hidp
->hid_dip
, hidp
->hid_interrupt_pipe
,
3280 &hidp
->hid_polled_raw_buf
,
3281 &hidp
->hid_polled_console_info
) != USB_SUCCESS
) {
3283 * If for some reason the lower layers cannot initialized, then
3286 (void) hid_polled_input_fini(hidp
);
3288 return (USB_FAILURE
);
3291 return (USB_SUCCESS
);
3296 * hid_polled_input_fini:
3297 * This routine is called when we are done using this device as an input
3301 hid_polled_input_fini(hid_state_t
*hidp
)
3303 USB_DPRINTF_L4(PRINT_MASK_ALL
, hidp
->hid_log_handle
,
3304 "hid_polled_input_fini");
3307 * Call the lower layers to free any state information
3308 * only if polled input has been initialised.
3310 if ((hidp
->hid_polled_console_info
) &&
3311 (usb_console_input_fini(hidp
->hid_polled_console_info
) !=
3314 return (USB_FAILURE
);
3316 hidp
->hid_polled_console_info
= NULL
;
3318 return (USB_SUCCESS
);
3323 * hid_polled_input_enter:
3324 * This is the routine that is called in polled mode to save the USB
3325 * state information before using the USB keyboard as an input device.
3326 * This routine, and all of the routines that it calls, are responsible
3327 * for saving any state information so that it can be restored when
3328 * polling mode is over.
3332 hid_polled_input_enter(hid_polled_handle_t hid_polled_inputp
)
3334 hid_state_t
*hidp
= (hid_state_t
*)hid_polled_inputp
;
3337 * Call the lower layers to tell them to save any state information.
3339 (void) usb_console_input_enter(hidp
->hid_polled_console_info
);
3341 return (USB_SUCCESS
);
3347 * This is the routine that is called in polled mode when it wants to read
3348 * a character. We will call to the lower layers to see if there is any
3349 * input data available. If there is USB scancodes available, we will
3353 hid_polled_read(hid_polled_handle_t hid_polled_input
, uchar_t
**buffer
)
3355 hid_state_t
*hidp
= (hid_state_t
*)hid_polled_input
;
3359 * Call the lower layers to get the character from the controller.
3360 * The lower layers will return the number of characters that
3361 * were put in the raw buffer. The address of the raw buffer
3362 * was passed down to the lower layers during hid_polled_init.
3364 if (usb_console_read(hidp
->hid_polled_console_info
,
3365 &num_bytes
) != USB_SUCCESS
) {
3370 _NOTE(NO_COMPETING_THREADS_NOW
);
3372 *buffer
= hidp
->hid_polled_raw_buf
;
3374 _NOTE(COMPETING_THREADS_NOW
);
3377 * Return the number of characters that were copied into the
3385 * hid_polled_input_exit :
3386 * This is the routine that is called in polled mode when it is giving up
3387 * control of the USB keyboard. This routine, and the lower layer routines
3388 * that it calls, are responsible for restoring the controller state to the
3389 * state it was in before polled mode.
3392 hid_polled_input_exit(hid_polled_handle_t hid_polled_inputp
)
3394 hid_state_t
*hidp
= (hid_state_t
*)hid_polled_inputp
;
3397 * Call the lower layers to restore any state information.
3399 (void) usb_console_input_exit(hidp
->hid_polled_console_info
);