1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * HID spec: https://www.usb.org/sites/default/files/documents/hid1_11.pdf
35 */
36
37 #include <sys/stdint.h>
38 #include <sys/stddef.h>
39 #include <sys/param.h>
40 #include <sys/queue.h>
41 #include <sys/types.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/bus.h>
45 #include <sys/module.h>
46 #include <sys/lock.h>
47 #include <sys/mutex.h>
48 #include <sys/condvar.h>
49 #include <sys/sysctl.h>
50 #include <sys/sx.h>
51 #include <sys/unistd.h>
52 #include <sys/callout.h>
53 #include <sys/malloc.h>
54 #include <sys/priv.h>
55 #include <sys/conf.h>
56 #include <sys/fcntl.h>
57
58 #include <dev/evdev/input.h>
59
60 #include <dev/hid/hid.h>
61 #include <dev/hid/hidquirk.h>
62
63 #include <dev/usb/usb.h>
64 #include <dev/usb/usbdi.h>
65 #include <dev/usb/usbdi_util.h>
66 #include <dev/usb/usbhid.h>
67 #include <dev/usb/usb_core.h>
68 #include <dev/usb/usb_ioctl.h>
69 #include <dev/usb/usb_util.h>
70
71 #define USB_DEBUG_VAR usbhid_debug
72 #include <dev/usb/usb_debug.h>
73
74 #include <dev/usb/quirk/usb_quirk.h>
75
76 #include "hid_if.h"
77
78 static SYSCTL_NODE(_hw_usb, OID_AUTO, usbhid, CTLFLAG_RW, 0, "USB usbhid");
79 static int usbhid_enable = 0;
80 SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, enable, CTLFLAG_RWTUN,
81 &usbhid_enable, 0, "Enable usbhid and prefer it to other USB HID drivers");
82 #ifdef USB_DEBUG
83 static int usbhid_debug = 0;
84 SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, debug, CTLFLAG_RWTUN,
85 &usbhid_debug, 0, "Debug level");
86 #endif
87
88 /* Second set of USB transfers for polling mode */
89 #define POLL_XFER(xfer) ((xfer) + USBHID_N_TRANSFER)
90 enum {
91 USBHID_INTR_OUT_DT,
92 USBHID_INTR_IN_DT,
93 USBHID_CTRL_DT,
94 USBHID_N_TRANSFER,
95 };
96
97 struct usbhid_xfer_ctx;
98 typedef int usbhid_callback_t(struct usbhid_xfer_ctx *xfer_ctx);
99
100 union usbhid_device_request {
101 struct { /* INTR xfers */
102 uint16_t maxlen;
103 uint16_t actlen;
104 } intr;
105 struct usb_device_request ctrl; /* CTRL xfers */
106 };
107
108 /* Syncronous USB transfer context */
109 struct usbhid_xfer_ctx {
110 union usbhid_device_request req;
111 uint8_t *buf;
112 int error;
113 usbhid_callback_t *cb;
114 void *cb_ctx;
115 int waiters;
116 bool influx;
117 };
118
119 struct usbhid_softc {
120 hid_intr_t *sc_intr_handler;
121 void *sc_intr_ctx;
122 void *sc_intr_buf;
123
124 struct hid_device_info sc_hw;
125
126 struct mtx sc_mtx;
127 struct usb_config sc_config[USBHID_N_TRANSFER];
128 struct usb_xfer *sc_xfer[POLL_XFER(USBHID_N_TRANSFER)];
129 struct usbhid_xfer_ctx sc_xfer_ctx[POLL_XFER(USBHID_N_TRANSFER)];
130 bool sc_can_poll;
131
132 struct usb_device *sc_udev;
133 uint8_t sc_iface_no;
134 uint8_t sc_iface_index;
135 };
136
137 /* prototypes */
138
139 static device_probe_t usbhid_probe;
140 static device_attach_t usbhid_attach;
141 static device_detach_t usbhid_detach;
142
143 static usb_callback_t usbhid_intr_out_callback;
144 static usb_callback_t usbhid_intr_in_callback;
145 static usb_callback_t usbhid_ctrl_callback;
146
147 static usbhid_callback_t usbhid_intr_handler_cb;
148 static usbhid_callback_t usbhid_sync_wakeup_cb;
149
150 static void
usbhid_intr_out_callback(struct usb_xfer * xfer,usb_error_t error)151 usbhid_intr_out_callback(struct usb_xfer *xfer, usb_error_t error)
152 {
153 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
154 struct usb_page_cache *pc;
155 int len;
156
157 switch (USB_GET_STATE(xfer)) {
158 case USB_ST_TRANSFERRED:
159 case USB_ST_SETUP:
160 tr_setup:
161 len = xfer_ctx->req.intr.maxlen;
162 if (len == 0) {
163 if (USB_IN_POLLING_MODE_FUNC())
164 xfer_ctx->error = 0;
165 return;
166 }
167 pc = usbd_xfer_get_frame(xfer, 0);
168 usbd_copy_in(pc, 0, xfer_ctx->buf, len);
169 usbd_xfer_set_frame_len(xfer, 0, len);
170 usbd_transfer_submit(xfer);
171 xfer_ctx->req.intr.maxlen = 0;
172 if (USB_IN_POLLING_MODE_FUNC())
173 return;
174 xfer_ctx->error = 0;
175 goto tr_exit;
176
177 default: /* Error */
178 if (error != USB_ERR_CANCELLED) {
179 /* try to clear stall first */
180 usbd_xfer_set_stall(xfer);
181 goto tr_setup;
182 }
183 xfer_ctx->error = EIO;
184 tr_exit:
185 (void)xfer_ctx->cb(xfer_ctx);
186 return;
187 }
188 }
189
190 static void
usbhid_intr_in_callback(struct usb_xfer * xfer,usb_error_t error)191 usbhid_intr_in_callback(struct usb_xfer *xfer, usb_error_t error)
192 {
193 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
194 struct usb_page_cache *pc;
195 int actlen;
196
197 switch (USB_GET_STATE(xfer)) {
198 case USB_ST_TRANSFERRED:
199 DPRINTF("transferred!\n");
200
201 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
202 pc = usbd_xfer_get_frame(xfer, 0);
203 usbd_copy_out(pc, 0, xfer_ctx->buf, actlen);
204 xfer_ctx->req.intr.actlen = actlen;
205 if (xfer_ctx->cb(xfer_ctx) != 0)
206 return;
207
208 case USB_ST_SETUP:
209 re_submit:
210 usbd_xfer_set_frame_len(xfer, 0, xfer_ctx->req.intr.maxlen);
211 usbd_transfer_submit(xfer);
212 return;
213
214 default: /* Error */
215 if (error != USB_ERR_CANCELLED) {
216 /* try to clear stall first */
217 usbd_xfer_set_stall(xfer);
218 goto re_submit;
219 }
220 return;
221 }
222 }
223
224 static void
usbhid_ctrl_callback(struct usb_xfer * xfer,usb_error_t error)225 usbhid_ctrl_callback(struct usb_xfer *xfer, usb_error_t error)
226 {
227 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
228 struct usb_device_request *req = &xfer_ctx->req.ctrl;
229 struct usb_page_cache *pc;
230 int len = UGETW(req->wLength);
231 bool is_rd = (req->bmRequestType & UT_READ) != 0;
232
233 switch (USB_GET_STATE(xfer)) {
234 case USB_ST_SETUP:
235 if (!is_rd && len != 0) {
236 pc = usbd_xfer_get_frame(xfer, 1);
237 usbd_copy_in(pc, 0, xfer_ctx->buf, len);
238 }
239
240 pc = usbd_xfer_get_frame(xfer, 0);
241 usbd_copy_in(pc, 0, req, sizeof(*req));
242 usbd_xfer_set_frame_len(xfer, 0, sizeof(*req));
243 if (len != 0)
244 usbd_xfer_set_frame_len(xfer, 1, len);
245 usbd_xfer_set_frames(xfer, len != 0 ? 2 : 1);
246 usbd_transfer_submit(xfer);
247 return;
248
249 case USB_ST_TRANSFERRED:
250 if (is_rd && len != 0) {
251 pc = usbd_xfer_get_frame(xfer, 0);
252 usbd_copy_out(pc, sizeof(*req), xfer_ctx->buf, len);
253 }
254 xfer_ctx->error = 0;
255 goto tr_exit;
256
257 default: /* Error */
258 /* bomb out */
259 DPRINTFN(1, "error=%s\n", usbd_errstr(error));
260 xfer_ctx->error = EIO;
261 tr_exit:
262 (void)xfer_ctx->cb(xfer_ctx);
263 return;
264 }
265 }
266
267 static int
usbhid_intr_handler_cb(struct usbhid_xfer_ctx * xfer_ctx)268 usbhid_intr_handler_cb(struct usbhid_xfer_ctx *xfer_ctx)
269 {
270 struct usbhid_softc *sc = xfer_ctx->cb_ctx;
271
272 sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf,
273 xfer_ctx->req.intr.actlen);
274
275 return (0);
276 }
277
278 static int
usbhid_sync_wakeup_cb(struct usbhid_xfer_ctx * xfer_ctx)279 usbhid_sync_wakeup_cb(struct usbhid_xfer_ctx *xfer_ctx)
280 {
281
282 if (!USB_IN_POLLING_MODE_FUNC())
283 wakeup(xfer_ctx->cb_ctx);
284
285 return (ECANCELED);
286 }
287
288 static const struct usb_config usbhid_config[USBHID_N_TRANSFER] = {
289
290 [USBHID_INTR_OUT_DT] = {
291 .type = UE_INTERRUPT,
292 .endpoint = UE_ADDR_ANY,
293 .direction = UE_DIR_OUT,
294 .flags = {.pipe_bof = 1,.proxy_buffer = 1},
295 .callback = &usbhid_intr_out_callback,
296 },
297 [USBHID_INTR_IN_DT] = {
298 .type = UE_INTERRUPT,
299 .endpoint = UE_ADDR_ANY,
300 .direction = UE_DIR_IN,
301 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1},
302 .callback = &usbhid_intr_in_callback,
303 },
304 [USBHID_CTRL_DT] = {
305 .type = UE_CONTROL,
306 .endpoint = 0x00, /* Control pipe */
307 .direction = UE_DIR_ANY,
308 .flags = {.proxy_buffer = 1},
309 .callback = &usbhid_ctrl_callback,
310 .timeout = 1000, /* 1 second */
311 },
312 };
313
314 static inline usb_frlength_t
usbhid_xfer_max_len(struct usb_xfer * xfer)315 usbhid_xfer_max_len(struct usb_xfer *xfer)
316 {
317 return (xfer == NULL ? 0 : usbd_xfer_max_len(xfer));
318 }
319
320 static inline int
usbhid_xfer_check_len(struct usbhid_softc * sc,int xfer_idx,hid_size_t len)321 usbhid_xfer_check_len(struct usbhid_softc* sc, int xfer_idx, hid_size_t len)
322 {
323 if (USB_IN_POLLING_MODE_FUNC())
324 xfer_idx = POLL_XFER(xfer_idx);
325 if (sc->sc_xfer[xfer_idx] == NULL)
326 return (ENODEV);
327 if (len > usbd_xfer_max_len(sc->sc_xfer[xfer_idx]))
328 return (ENOBUFS);
329 return (0);
330 }
331
332 static void
usbhid_intr_setup(device_t dev,device_t child __unused,hid_intr_t intr,void * context,struct hid_rdesc_info * rdesc)333 usbhid_intr_setup(device_t dev, device_t child __unused, hid_intr_t intr,
334 void *context, struct hid_rdesc_info *rdesc)
335 {
336 struct usbhid_softc* sc = device_get_softc(dev);
337 uint16_t n;
338 bool nowrite;
339 int error;
340
341 nowrite = hid_test_quirk(&sc->sc_hw, HQ_NOWRITE);
342
343 /*
344 * Setup the USB transfers one by one, so they are memory independent
345 * which allows for handling panics triggered by the HID drivers
346 * itself, typically by hkbd via CTRL+ALT+ESC sequences. Or if the HID
347 * keyboard driver was processing a key at the moment of panic.
348 */
349 if (intr == NULL) {
350 if (sc->sc_can_poll)
351 return;
352 for (n = 0; n != USBHID_N_TRANSFER; n++) {
353 if (nowrite && n == USBHID_INTR_OUT_DT)
354 continue;
355 error = usbd_transfer_setup(sc->sc_udev,
356 &sc->sc_iface_index, sc->sc_xfer + POLL_XFER(n),
357 sc->sc_config + n, 1,
358 (void *)(sc->sc_xfer_ctx + POLL_XFER(n)),
359 &sc->sc_mtx);
360 if (error)
361 DPRINTF("xfer %d setup error=%s\n", n,
362 usbd_errstr(error));
363 }
364 mtx_lock(&sc->sc_mtx);
365 if (sc->sc_xfer[USBHID_INTR_IN_DT] != NULL &&
366 sc->sc_xfer[USBHID_INTR_IN_DT]->flags_int.started)
367 usbd_transfer_start(
368 sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
369 mtx_unlock(&sc->sc_mtx);
370 sc->sc_can_poll = true;
371 return;
372 }
373
374 sc->sc_intr_handler = intr;
375 sc->sc_intr_ctx = context;
376 bcopy(usbhid_config, sc->sc_config, sizeof(usbhid_config));
377 bzero(sc->sc_xfer, sizeof(sc->sc_xfer));
378
379 /* Set buffer sizes to match HID report sizes */
380 sc->sc_config[USBHID_INTR_OUT_DT].bufsize = rdesc->osize;
381 sc->sc_config[USBHID_INTR_IN_DT].bufsize = rdesc->isize;
382 sc->sc_config[USBHID_CTRL_DT].bufsize =
383 MAX(rdesc->isize, MAX(rdesc->osize, rdesc->fsize));
384
385 for (n = 0; n != USBHID_N_TRANSFER; n++) {
386 if (nowrite && n == USBHID_INTR_OUT_DT)
387 continue;
388 error = usbd_transfer_setup(sc->sc_udev, &sc->sc_iface_index,
389 sc->sc_xfer + n, sc->sc_config + n, 1,
390 (void *)(sc->sc_xfer_ctx + n), &sc->sc_mtx);
391 if (error)
392 DPRINTF("xfer %d setup error=%s\n", n,
393 usbd_errstr(error));
394 }
395
396 rdesc->rdsize = usbhid_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]);
397 rdesc->grsize = usbhid_xfer_max_len(sc->sc_xfer[USBHID_CTRL_DT]);
398 rdesc->srsize = rdesc->grsize;
399 rdesc->wrsize = nowrite ? rdesc->srsize :
400 usbhid_xfer_max_len(sc->sc_xfer[USBHID_INTR_OUT_DT]);
401
402 sc->sc_intr_buf = malloc(rdesc->rdsize, M_USBDEV, M_ZERO | M_WAITOK);
403 }
404
405 static void
usbhid_intr_unsetup(device_t dev,device_t child __unused)406 usbhid_intr_unsetup(device_t dev, device_t child __unused)
407 {
408 struct usbhid_softc* sc = device_get_softc(dev);
409
410 usbd_transfer_unsetup(sc->sc_xfer, USBHID_N_TRANSFER);
411 if (sc->sc_can_poll)
412 usbd_transfer_unsetup(
413 sc->sc_xfer, POLL_XFER(USBHID_N_TRANSFER));
414 sc->sc_can_poll = false;
415 free(sc->sc_intr_buf, M_USBDEV);
416 }
417
418 static int
usbhid_intr_start(device_t dev,device_t child __unused)419 usbhid_intr_start(device_t dev, device_t child __unused)
420 {
421 struct usbhid_softc* sc = device_get_softc(dev);
422
423 if (sc->sc_xfer[USBHID_INTR_IN_DT] == NULL)
424 return (ENODEV);
425
426 mtx_lock(&sc->sc_mtx);
427 sc->sc_xfer_ctx[USBHID_INTR_IN_DT] = (struct usbhid_xfer_ctx) {
428 .req.intr.maxlen =
429 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]),
430 .cb = usbhid_intr_handler_cb,
431 .cb_ctx = sc,
432 .buf = sc->sc_intr_buf,
433 };
434 sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct usbhid_xfer_ctx) {
435 .req.intr.maxlen =
436 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]),
437 .cb = usbhid_intr_handler_cb,
438 .cb_ctx = sc,
439 .buf = sc->sc_intr_buf,
440 };
441 usbd_transfer_start(sc->sc_xfer[USBHID_INTR_IN_DT]);
442 if (sc->sc_can_poll)
443 usbd_transfer_start(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
444 mtx_unlock(&sc->sc_mtx);
445
446 return (0);
447 }
448
449 static int
usbhid_intr_stop(device_t dev,device_t child __unused)450 usbhid_intr_stop(device_t dev, device_t child __unused)
451 {
452 struct usbhid_softc* sc = device_get_softc(dev);
453
454 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_IN_DT]);
455 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_OUT_DT]);
456 if (sc->sc_can_poll)
457 usbd_transfer_drain(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
458
459 return (0);
460 }
461
462 static void
usbhid_intr_poll(device_t dev,device_t child __unused)463 usbhid_intr_poll(device_t dev, device_t child __unused)
464 {
465 struct usbhid_softc* sc = device_get_softc(dev);
466
467 MPASS(sc->sc_can_poll);
468 usbd_transfer_poll(sc->sc_xfer + USBHID_INTR_IN_DT, 1);
469 usbd_transfer_poll(sc->sc_xfer + POLL_XFER(USBHID_INTR_IN_DT), 1);
470 }
471
472 /*
473 * HID interface
474 */
475 static int
usbhid_sync_xfer(struct usbhid_softc * sc,int xfer_idx,union usbhid_device_request * req,void * buf)476 usbhid_sync_xfer(struct usbhid_softc* sc, int xfer_idx,
477 union usbhid_device_request *req, void *buf)
478 {
479 int error, timeout;
480 struct usbhid_xfer_ctx *xfer_ctx;
481
482 xfer_ctx = sc->sc_xfer_ctx + xfer_idx;
483
484 if (USB_IN_POLLING_MODE_FUNC()) {
485 xfer_ctx = POLL_XFER(xfer_ctx);
486 xfer_idx = POLL_XFER(xfer_idx);
487 } else {
488 mtx_lock(&sc->sc_mtx);
489 ++xfer_ctx->waiters;
490 while (xfer_ctx->influx)
491 mtx_sleep(&xfer_ctx->waiters, &sc->sc_mtx, 0,
492 "usbhid wt", 0);
493 --xfer_ctx->waiters;
494 xfer_ctx->influx = true;
495 }
496
497 xfer_ctx->buf = buf;
498 xfer_ctx->req = *req;
499 xfer_ctx->error = ETIMEDOUT;
500 xfer_ctx->cb = &usbhid_sync_wakeup_cb;
501 xfer_ctx->cb_ctx = xfer_ctx;
502 timeout = USB_DEFAULT_TIMEOUT;
503 usbd_transfer_start(sc->sc_xfer[xfer_idx]);
504
505 if (USB_IN_POLLING_MODE_FUNC())
506 while (timeout > 0 && xfer_ctx->error == ETIMEDOUT) {
507 usbd_transfer_poll(sc->sc_xfer + xfer_idx, 1);
508 DELAY(1000);
509 timeout--;
510 }
511 else
512 msleep_sbt(xfer_ctx, &sc->sc_mtx, 0, "usbhid io",
513 SBT_1MS * timeout, 0, C_HARDCLOCK);
514
515 /* Perform usbhid_write() asyncronously to improve pipelining */
516 if (USB_IN_POLLING_MODE_FUNC() || xfer_ctx->error != 0 ||
517 sc->sc_config[xfer_idx].type != UE_INTERRUPT ||
518 sc->sc_config[xfer_idx].direction != UE_DIR_OUT)
519 usbd_transfer_stop(sc->sc_xfer[xfer_idx]);
520 error = xfer_ctx->error;
521 if (error == 0)
522 *req = xfer_ctx->req;
523
524 if (!USB_IN_POLLING_MODE_FUNC()) {
525 xfer_ctx->influx = false;
526 if (xfer_ctx->waiters != 0)
527 wakeup_one(&xfer_ctx->waiters);
528 mtx_unlock(&sc->sc_mtx);
529 }
530
531 if (error)
532 DPRINTF("USB IO error:%d\n", error);
533
534 return (error);
535 }
536
537 static int
usbhid_get_rdesc(device_t dev,device_t child __unused,void * buf,hid_size_t len)538 usbhid_get_rdesc(device_t dev, device_t child __unused, void *buf,
539 hid_size_t len)
540 {
541 struct usbhid_softc* sc = device_get_softc(dev);
542 int error;
543
544 error = usbd_req_get_report_descriptor(sc->sc_udev, NULL,
545 buf, len, sc->sc_iface_index);
546
547 if (error)
548 DPRINTF("no report descriptor: %s\n", usbd_errstr(error));
549
550 return (error == 0 ? 0 : ENXIO);
551 }
552
553 static int
usbhid_get_report(device_t dev,device_t child __unused,void * buf,hid_size_t maxlen,hid_size_t * actlen,uint8_t type,uint8_t id)554 usbhid_get_report(device_t dev, device_t child __unused, void *buf,
555 hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id)
556 {
557 struct usbhid_softc* sc = device_get_softc(dev);
558 union usbhid_device_request req;
559 int error;
560
561 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, maxlen);
562 if (error)
563 return (error);
564
565 req.ctrl.bmRequestType = UT_READ_CLASS_INTERFACE;
566 req.ctrl.bRequest = UR_GET_REPORT;
567 USETW2(req.ctrl.wValue, type, id);
568 req.ctrl.wIndex[0] = sc->sc_iface_no;
569 req.ctrl.wIndex[1] = 0;
570 USETW(req.ctrl.wLength, maxlen);
571
572 error = usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, buf);
573 if (!error && actlen != NULL)
574 *actlen = maxlen;
575
576 return (error);
577 }
578
579 static int
usbhid_set_report(device_t dev,device_t child __unused,const void * buf,hid_size_t len,uint8_t type,uint8_t id)580 usbhid_set_report(device_t dev, device_t child __unused, const void *buf,
581 hid_size_t len, uint8_t type, uint8_t id)
582 {
583 struct usbhid_softc* sc = device_get_softc(dev);
584 union usbhid_device_request req;
585 int error;
586
587 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, len);
588 if (error)
589 return (error);
590
591 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
592 req.ctrl.bRequest = UR_SET_REPORT;
593 USETW2(req.ctrl.wValue, type, id);
594 req.ctrl.wIndex[0] = sc->sc_iface_no;
595 req.ctrl.wIndex[1] = 0;
596 USETW(req.ctrl.wLength, len);
597
598 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req,
599 __DECONST(void *, buf)));
600 }
601
602 static int
usbhid_read(device_t dev,device_t child __unused,void * buf,hid_size_t maxlen,hid_size_t * actlen)603 usbhid_read(device_t dev, device_t child __unused, void *buf,
604 hid_size_t maxlen, hid_size_t *actlen)
605 {
606 struct usbhid_softc* sc = device_get_softc(dev);
607 union usbhid_device_request req;
608 int error;
609
610 error = usbhid_xfer_check_len(sc, USBHID_INTR_IN_DT, maxlen);
611 if (error)
612 return (error);
613
614 req.intr.maxlen = maxlen;
615 error = usbhid_sync_xfer(sc, USBHID_INTR_IN_DT, &req, buf);
616 if (error == 0 && actlen != NULL)
617 *actlen = req.intr.actlen;
618
619 return (error);
620 }
621
622 static int
usbhid_write(device_t dev,device_t child __unused,const void * buf,hid_size_t len)623 usbhid_write(device_t dev, device_t child __unused, const void *buf,
624 hid_size_t len)
625 {
626 struct usbhid_softc* sc = device_get_softc(dev);
627 union usbhid_device_request req;
628 int error;
629
630 error = usbhid_xfer_check_len(sc, USBHID_INTR_OUT_DT, len);
631 if (error)
632 return (error);
633
634 req.intr.maxlen = len;
635 return (usbhid_sync_xfer(sc, USBHID_INTR_OUT_DT, &req,
636 __DECONST(void *, buf)));
637 }
638
639 static int
usbhid_set_idle(device_t dev,device_t child __unused,uint16_t duration,uint8_t id)640 usbhid_set_idle(device_t dev, device_t child __unused, uint16_t duration,
641 uint8_t id)
642 {
643 struct usbhid_softc* sc = device_get_softc(dev);
644 union usbhid_device_request req;
645 int error;
646
647 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
648 if (error)
649 return (error);
650
651 /* Duration is measured in 4 milliseconds per unit. */
652 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
653 req.ctrl.bRequest = UR_SET_IDLE;
654 USETW2(req.ctrl.wValue, (duration + 3) / 4, id);
655 req.ctrl.wIndex[0] = sc->sc_iface_no;
656 req.ctrl.wIndex[1] = 0;
657 USETW(req.ctrl.wLength, 0);
658
659 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
660 }
661
662 static int
usbhid_set_protocol(device_t dev,device_t child __unused,uint16_t protocol)663 usbhid_set_protocol(device_t dev, device_t child __unused, uint16_t protocol)
664 {
665 struct usbhid_softc* sc = device_get_softc(dev);
666 union usbhid_device_request req;
667 int error;
668
669 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
670 if (error)
671 return (error);
672
673 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
674 req.ctrl.bRequest = UR_SET_PROTOCOL;
675 USETW(req.ctrl.wValue, protocol);
676 req.ctrl.wIndex[0] = sc->sc_iface_no;
677 req.ctrl.wIndex[1] = 0;
678 USETW(req.ctrl.wLength, 0);
679
680 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
681 }
682
683 static int
usbhid_ioctl(device_t dev,device_t child __unused,unsigned long cmd,uintptr_t data)684 usbhid_ioctl(device_t dev, device_t child __unused, unsigned long cmd,
685 uintptr_t data)
686 {
687 struct usbhid_softc* sc = device_get_softc(dev);
688 struct usb_ctl_request *ucr;
689 union usbhid_device_request req;
690 int error;
691
692 switch (cmd) {
693 case USB_REQUEST:
694 ucr = (struct usb_ctl_request *)data;
695 req.ctrl = ucr->ucr_request;
696 error = usbhid_xfer_check_len(
697 sc, USBHID_CTRL_DT, UGETW(req.ctrl.wLength));
698 if (error)
699 break;
700 error = usb_check_request(sc->sc_udev, &req.ctrl);
701 if (error)
702 break;
703 error = usbhid_sync_xfer(
704 sc, USBHID_CTRL_DT, &req, ucr->ucr_data);
705 if (error == 0)
706 ucr->ucr_actlen = UGETW(req.ctrl.wLength);
707 break;
708 default:
709 error = EINVAL;
710 }
711
712 return (error);
713 }
714
715 static void
usbhid_init_device_info(struct usb_attach_arg * uaa,struct hid_device_info * hw)716 usbhid_init_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
717 {
718
719 hw->idBus = BUS_USB;
720 hw->idVendor = uaa->info.idVendor;
721 hw->idProduct = uaa->info.idProduct;
722 hw->idVersion = uaa->info.bcdDevice;
723
724 /* Set various quirks based on usb_attach_arg */
725 hid_add_dynamic_quirk(hw, USB_GET_DRIVER_INFO(uaa));
726 }
727
728 static void
usbhid_fill_device_info(struct usb_attach_arg * uaa,struct hid_device_info * hw)729 usbhid_fill_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
730 {
731 struct usb_device *udev = uaa->device;
732 struct usb_interface *iface = uaa->iface;
733 struct usb_hid_descriptor *hid;
734 struct usb_endpoint *ep;
735
736 snprintf(hw->name, sizeof(hw->name), "%s %s",
737 usb_get_manufacturer(udev), usb_get_product(udev));
738 strlcpy(hw->serial, usb_get_serial(udev), sizeof(hw->serial));
739
740 if (uaa->info.bInterfaceClass == UICLASS_HID &&
741 iface != NULL && iface->idesc != NULL) {
742 hid = hid_get_descriptor_from_usb(
743 usbd_get_config_descriptor(udev), iface->idesc);
744 if (hid != NULL)
745 hw->rdescsize =
746 UGETW(hid->descrs[0].wDescriptorLength);
747 }
748
749 /* See if there is a interrupt out endpoint. */
750 ep = usbd_get_endpoint(udev, uaa->info.bIfaceIndex,
751 usbhid_config + USBHID_INTR_OUT_DT);
752 if (ep == NULL || ep->methods == NULL)
753 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
754 }
755
756 static const STRUCT_USB_HOST_ID usbhid_devs[] = {
757 /* the Xbox 360 gamepad doesn't use the HID class */
758 {USB_IFACE_CLASS(UICLASS_VENDOR),
759 USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER),
760 USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),
761 USB_DRIVER_INFO(HQ_IS_XBOX360GP)},
762 /* HID keyboard with boot protocol support */
763 {USB_IFACE_CLASS(UICLASS_HID),
764 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
765 USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),
766 USB_DRIVER_INFO(HQ_HAS_KBD_BOOTPROTO)},
767 /* HID mouse with boot protocol support */
768 {USB_IFACE_CLASS(UICLASS_HID),
769 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
770 USB_IFACE_PROTOCOL(UIPROTO_MOUSE),
771 USB_DRIVER_INFO(HQ_HAS_MS_BOOTPROTO)},
772 /* generic HID class */
773 {USB_IFACE_CLASS(UICLASS_HID), USB_DRIVER_INFO(HQ_NONE)},
774 };
775
776 static int
usbhid_probe(device_t dev)777 usbhid_probe(device_t dev)
778 {
779 struct usb_attach_arg *uaa = device_get_ivars(dev);
780 struct usbhid_softc *sc = device_get_softc(dev);
781 int error;
782
783 DPRINTFN(11, "\n");
784
785 if (usbhid_enable == 0)
786 return (ENXIO);
787
788 if (uaa->usb_mode != USB_MODE_HOST)
789 return (ENXIO);
790
791 error = usbd_lookup_id_by_uaa(usbhid_devs, sizeof(usbhid_devs), uaa);
792 if (error)
793 return (error);
794
795 if (usb_test_quirk(uaa, UQ_HID_IGNORE))
796 return (ENXIO);
797
798 /*
799 * Setup temporary hid_device_info so that we can figure out some
800 * basic quirks for this device.
801 */
802 usbhid_init_device_info(uaa, &sc->sc_hw);
803
804 if (hid_test_quirk(&sc->sc_hw, HQ_HID_IGNORE))
805 return (ENXIO);
806
807 return (BUS_PROBE_DEFAULT + 1);
808 }
809
810 static int
usbhid_attach(device_t dev)811 usbhid_attach(device_t dev)
812 {
813 struct usb_attach_arg *uaa = device_get_ivars(dev);
814 struct usbhid_softc *sc = device_get_softc(dev);
815 device_t child;
816 int error = 0;
817
818 DPRINTFN(10, "sc=%p\n", sc);
819
820 device_set_usb_desc(dev);
821
822 sc->sc_udev = uaa->device;
823 sc->sc_iface_no = uaa->info.bIfaceNum;
824 sc->sc_iface_index = uaa->info.bIfaceIndex;
825
826 usbhid_fill_device_info(uaa, &sc->sc_hw);
827
828 error = usbd_req_set_idle(uaa->device, NULL,
829 uaa->info.bIfaceIndex, 0, 0);
830 if (error)
831 DPRINTF("set idle failed, error=%s (ignored)\n",
832 usbd_errstr(error));
833
834 mtx_init(&sc->sc_mtx, "usbhid lock", NULL, MTX_DEF);
835
836 child = device_add_child(dev, "hidbus", DEVICE_UNIT_ANY);
837 if (child == NULL) {
838 device_printf(dev, "Could not add hidbus device\n");
839 usbhid_detach(dev);
840 return (ENOMEM);
841 }
842
843 device_set_ivars(child, &sc->sc_hw);
844 bus_attach_children(dev);
845
846 return (0); /* success */
847 }
848
849 static int
usbhid_detach(device_t dev)850 usbhid_detach(device_t dev)
851 {
852 struct usbhid_softc *sc = device_get_softc(dev);
853 int error;
854
855 error = bus_generic_detach(dev);
856 if (error != 0)
857 return (error);
858
859 mtx_destroy(&sc->sc_mtx);
860
861 return (0);
862 }
863
864 static device_method_t usbhid_methods[] = {
865 DEVMETHOD(device_probe, usbhid_probe),
866 DEVMETHOD(device_attach, usbhid_attach),
867 DEVMETHOD(device_detach, usbhid_detach),
868
869 DEVMETHOD(hid_intr_setup, usbhid_intr_setup),
870 DEVMETHOD(hid_intr_unsetup, usbhid_intr_unsetup),
871 DEVMETHOD(hid_intr_start, usbhid_intr_start),
872 DEVMETHOD(hid_intr_stop, usbhid_intr_stop),
873 DEVMETHOD(hid_intr_poll, usbhid_intr_poll),
874
875 /* HID interface */
876 DEVMETHOD(hid_get_rdesc, usbhid_get_rdesc),
877 DEVMETHOD(hid_read, usbhid_read),
878 DEVMETHOD(hid_write, usbhid_write),
879 DEVMETHOD(hid_get_report, usbhid_get_report),
880 DEVMETHOD(hid_set_report, usbhid_set_report),
881 DEVMETHOD(hid_set_idle, usbhid_set_idle),
882 DEVMETHOD(hid_set_protocol, usbhid_set_protocol),
883 DEVMETHOD(hid_ioctl, usbhid_ioctl),
884
885 DEVMETHOD_END
886 };
887
888 static driver_t usbhid_driver = {
889 .name = "usbhid",
890 .methods = usbhid_methods,
891 .size = sizeof(struct usbhid_softc),
892 };
893
894 DRIVER_MODULE(usbhid, uhub, usbhid_driver, NULL, NULL);
895 MODULE_DEPEND(usbhid, usb, 1, 1, 1);
896 MODULE_DEPEND(usbhid, hid, 1, 1, 1);
897 MODULE_DEPEND(usbhid, hidbus, 1, 1, 1);
898 MODULE_VERSION(usbhid, 1);
899 USB_PNP_HOST_INFO(usbhid_devs);
900