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