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