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