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