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