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