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 = 1;
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 bool no_readahead;
118 };
119
120 struct usbhid_softc {
121 hid_intr_t *sc_intr_handler;
122 void *sc_intr_ctx;
123 void *sc_intr_buf;
124
125 struct hid_device_info sc_hw;
126
127 struct mtx sc_mtx;
128 struct usb_config sc_config[USBHID_N_TRANSFER];
129 struct usb_xfer *sc_xfer[POLL_XFER(USBHID_N_TRANSFER)];
130 struct usbhid_xfer_ctx sc_xfer_ctx[POLL_XFER(USBHID_N_TRANSFER)];
131 bool sc_can_poll;
132
133 struct usb_device *sc_udev;
134 uint8_t sc_iface_no;
135 uint8_t sc_iface_index;
136 };
137
138 /* prototypes */
139
140 static device_probe_t usbhid_probe;
141 static device_attach_t usbhid_attach;
142 static device_detach_t usbhid_detach;
143
144 static usb_callback_t usbhid_intr_out_callback;
145 static usb_callback_t usbhid_intr_in_callback;
146 static usb_callback_t usbhid_ctrl_callback;
147
148 static usbhid_callback_t usbhid_intr_handler_cb;
149 static usbhid_callback_t usbhid_sync_wakeup_cb;
150
151 static void
usbhid_intr_out_callback(struct usb_xfer * xfer,usb_error_t error)152 usbhid_intr_out_callback(struct usb_xfer *xfer, usb_error_t error)
153 {
154 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
155 struct usb_page_cache *pc;
156 int len;
157
158 switch (USB_GET_STATE(xfer)) {
159 case USB_ST_TRANSFERRED:
160 case USB_ST_SETUP:
161 tr_setup:
162 len = xfer_ctx->req.intr.maxlen;
163 if (len == 0) {
164 if (USB_IN_POLLING_MODE_FUNC())
165 xfer_ctx->error = 0;
166 return;
167 }
168 pc = usbd_xfer_get_frame(xfer, 0);
169 usbd_copy_in(pc, 0, xfer_ctx->buf, len);
170 usbd_xfer_set_frame_len(xfer, 0, len);
171 usbd_transfer_submit(xfer);
172 xfer_ctx->req.intr.maxlen = 0;
173 if (USB_IN_POLLING_MODE_FUNC())
174 return;
175 xfer_ctx->error = 0;
176 goto tr_exit;
177
178 default: /* Error */
179 if (error != USB_ERR_CANCELLED) {
180 /* try to clear stall first */
181 usbd_xfer_set_stall(xfer);
182 goto tr_setup;
183 }
184 xfer_ctx->error = EIO;
185 tr_exit:
186 (void)xfer_ctx->cb(xfer_ctx);
187 return;
188 }
189 }
190
191 static void
usbhid_intr_in_callback(struct usb_xfer * xfer,usb_error_t error)192 usbhid_intr_in_callback(struct usb_xfer *xfer, usb_error_t error)
193 {
194 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
195 struct usb_page_cache *pc;
196 int actlen;
197
198 switch (USB_GET_STATE(xfer)) {
199 case USB_ST_TRANSFERRED:
200 DPRINTF("transferred!\n");
201
202 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
203 pc = usbd_xfer_get_frame(xfer, 0);
204 usbd_copy_out(pc, 0, xfer_ctx->buf, actlen);
205 xfer_ctx->req.intr.actlen = actlen;
206 if (xfer_ctx->cb(xfer_ctx) != 0)
207 return;
208
209 case USB_ST_SETUP:
210 re_submit:
211 usbd_xfer_set_frame_len(xfer, 0, xfer_ctx->req.intr.maxlen);
212 usbd_transfer_submit(xfer);
213 return;
214
215 default: /* Error */
216 if (error != USB_ERR_CANCELLED) {
217 /* try to clear stall first */
218 usbd_xfer_set_stall(xfer);
219 goto re_submit;
220 }
221 return;
222 }
223 }
224
225 static void
usbhid_ctrl_callback(struct usb_xfer * xfer,usb_error_t error)226 usbhid_ctrl_callback(struct usb_xfer *xfer, usb_error_t error)
227 {
228 struct usbhid_xfer_ctx *xfer_ctx = usbd_xfer_softc(xfer);
229 struct usb_device_request *req = &xfer_ctx->req.ctrl;
230 struct usb_page_cache *pc;
231 int len = UGETW(req->wLength);
232 bool is_rd = (req->bmRequestType & UT_READ) != 0;
233
234 switch (USB_GET_STATE(xfer)) {
235 case USB_ST_SETUP:
236 if (!is_rd && len != 0) {
237 pc = usbd_xfer_get_frame(xfer, 1);
238 usbd_copy_in(pc, 0, xfer_ctx->buf, len);
239 }
240
241 pc = usbd_xfer_get_frame(xfer, 0);
242 usbd_copy_in(pc, 0, req, sizeof(*req));
243 usbd_xfer_set_frame_len(xfer, 0, sizeof(*req));
244 if (len != 0)
245 usbd_xfer_set_frame_len(xfer, 1, len);
246 usbd_xfer_set_frames(xfer, len != 0 ? 2 : 1);
247 usbd_transfer_submit(xfer);
248 return;
249
250 case USB_ST_TRANSFERRED:
251 if (is_rd && len != 0) {
252 pc = usbd_xfer_get_frame(xfer, 0);
253 usbd_copy_out(pc, sizeof(*req), xfer_ctx->buf, len);
254 }
255 xfer_ctx->error = 0;
256 goto tr_exit;
257
258 default: /* Error */
259 /* bomb out */
260 DPRINTFN(1, "error=%s\n", usbd_errstr(error));
261 xfer_ctx->error = EIO;
262 tr_exit:
263 (void)xfer_ctx->cb(xfer_ctx);
264 return;
265 }
266 }
267
268 static int
usbhid_intr_handler_cb(struct usbhid_xfer_ctx * xfer_ctx)269 usbhid_intr_handler_cb(struct usbhid_xfer_ctx *xfer_ctx)
270 {
271 struct usbhid_softc *sc = xfer_ctx->cb_ctx;
272
273 sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf,
274 xfer_ctx->req.intr.actlen);
275
276 return (xfer_ctx->no_readahead ? ECANCELED : 0);
277 }
278
279 static int
usbhid_sync_wakeup_cb(struct usbhid_xfer_ctx * xfer_ctx)280 usbhid_sync_wakeup_cb(struct usbhid_xfer_ctx *xfer_ctx)
281 {
282
283 if (!USB_IN_POLLING_MODE_FUNC())
284 wakeup(xfer_ctx->cb_ctx);
285
286 return (ECANCELED);
287 }
288
289 static const struct usb_config usbhid_config[USBHID_N_TRANSFER] = {
290
291 [USBHID_INTR_OUT_DT] = {
292 .type = UE_INTERRUPT,
293 .endpoint = UE_ADDR_ANY,
294 .direction = UE_DIR_OUT,
295 .flags = {.pipe_bof = 1,.proxy_buffer = 1},
296 .callback = &usbhid_intr_out_callback,
297 },
298 [USBHID_INTR_IN_DT] = {
299 .type = UE_INTERRUPT,
300 .endpoint = UE_ADDR_ANY,
301 .direction = UE_DIR_IN,
302 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1},
303 .callback = &usbhid_intr_in_callback,
304 },
305 [USBHID_CTRL_DT] = {
306 .type = UE_CONTROL,
307 .endpoint = 0x00, /* Control pipe */
308 .direction = UE_DIR_ANY,
309 .flags = {.proxy_buffer = 1},
310 .callback = &usbhid_ctrl_callback,
311 .timeout = 1000, /* 1 second */
312 },
313 };
314
315 static inline usb_frlength_t
usbhid_xfer_max_len(struct usb_xfer * xfer)316 usbhid_xfer_max_len(struct usb_xfer *xfer)
317 {
318 return (xfer == NULL ? 0 : usbd_xfer_max_len(xfer));
319 }
320
321 static inline int
usbhid_xfer_check_len(struct usbhid_softc * sc,int xfer_idx,hid_size_t len)322 usbhid_xfer_check_len(struct usbhid_softc* sc, int xfer_idx, hid_size_t len)
323 {
324 if (USB_IN_POLLING_MODE_FUNC())
325 xfer_idx = POLL_XFER(xfer_idx);
326 if (sc->sc_xfer[xfer_idx] == NULL)
327 return (ENODEV);
328 if (len > usbd_xfer_max_len(sc->sc_xfer[xfer_idx]))
329 return (ENOBUFS);
330 return (0);
331 }
332
333 static void
usbhid_intr_setup(device_t dev,device_t child __unused,hid_intr_t intr,void * context,struct hid_rdesc_info * rdesc)334 usbhid_intr_setup(device_t dev, device_t child __unused, hid_intr_t intr,
335 void *context, struct hid_rdesc_info *rdesc)
336 {
337 struct usbhid_softc* sc = device_get_softc(dev);
338 uint16_t n;
339 bool nowrite;
340 int error;
341
342 nowrite = hid_test_quirk(&sc->sc_hw, HQ_NOWRITE);
343
344 /*
345 * Setup the USB transfers one by one, so they are memory independent
346 * which allows for handling panics triggered by the HID drivers
347 * itself, typically by hkbd via CTRL+ALT+ESC sequences. Or if the HID
348 * keyboard driver was processing a key at the moment of panic.
349 */
350 if (intr == NULL) {
351 if (sc->sc_can_poll)
352 return;
353 for (n = 0; n != USBHID_N_TRANSFER; n++) {
354 if (nowrite && n == USBHID_INTR_OUT_DT)
355 continue;
356 error = usbd_transfer_setup(sc->sc_udev,
357 &sc->sc_iface_index, sc->sc_xfer + POLL_XFER(n),
358 sc->sc_config + n, 1,
359 (void *)(sc->sc_xfer_ctx + POLL_XFER(n)),
360 &sc->sc_mtx);
361 if (error)
362 DPRINTF("xfer %d setup error=%s\n", n,
363 usbd_errstr(error));
364 }
365 mtx_lock(&sc->sc_mtx);
366 if (sc->sc_xfer[USBHID_INTR_IN_DT] != NULL &&
367 sc->sc_xfer[USBHID_INTR_IN_DT]->flags_int.started)
368 usbd_transfer_start(
369 sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
370 mtx_unlock(&sc->sc_mtx);
371 sc->sc_can_poll = true;
372 return;
373 }
374
375 sc->sc_intr_handler = intr;
376 sc->sc_intr_ctx = context;
377 bcopy(usbhid_config, sc->sc_config, sizeof(usbhid_config));
378 bzero(sc->sc_xfer, sizeof(sc->sc_xfer));
379
380 /* Set buffer sizes to match HID report sizes */
381 sc->sc_config[USBHID_INTR_OUT_DT].bufsize = rdesc->osize;
382 sc->sc_config[USBHID_INTR_IN_DT].bufsize = rdesc->isize;
383 sc->sc_config[USBHID_CTRL_DT].bufsize =
384 MAX(rdesc->isize, MAX(rdesc->osize, rdesc->fsize));
385
386 for (n = 0; n != USBHID_N_TRANSFER; n++) {
387 if (nowrite && n == USBHID_INTR_OUT_DT)
388 continue;
389 error = usbd_transfer_setup(sc->sc_udev, &sc->sc_iface_index,
390 sc->sc_xfer + n, sc->sc_config + n, 1,
391 (void *)(sc->sc_xfer_ctx + n), &sc->sc_mtx);
392 if (error)
393 DPRINTF("xfer %d setup error=%s\n", n,
394 usbd_errstr(error));
395 }
396
397 rdesc->rdsize = usbhid_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]);
398 rdesc->grsize = usbhid_xfer_max_len(sc->sc_xfer[USBHID_CTRL_DT]);
399 rdesc->srsize = rdesc->grsize;
400 rdesc->wrsize = nowrite ? rdesc->srsize :
401 usbhid_xfer_max_len(sc->sc_xfer[USBHID_INTR_OUT_DT]);
402
403 sc->sc_intr_buf = malloc(rdesc->rdsize, M_USBDEV, M_ZERO | M_WAITOK);
404 }
405
406 static void
usbhid_intr_unsetup(device_t dev,device_t child __unused)407 usbhid_intr_unsetup(device_t dev, device_t child __unused)
408 {
409 struct usbhid_softc* sc = device_get_softc(dev);
410
411 usbd_transfer_unsetup(sc->sc_xfer, USBHID_N_TRANSFER);
412 if (sc->sc_can_poll)
413 usbd_transfer_unsetup(
414 sc->sc_xfer, POLL_XFER(USBHID_N_TRANSFER));
415 sc->sc_can_poll = false;
416 free(sc->sc_intr_buf, M_USBDEV);
417 }
418
419 static int
usbhid_intr_start(device_t dev,device_t child __unused)420 usbhid_intr_start(device_t dev, device_t child __unused)
421 {
422 struct usbhid_softc* sc = device_get_softc(dev);
423
424 if (sc->sc_xfer[USBHID_INTR_IN_DT] == NULL)
425 return (ENODEV);
426
427 mtx_lock(&sc->sc_mtx);
428 sc->sc_xfer_ctx[USBHID_INTR_IN_DT] = (struct usbhid_xfer_ctx) {
429 .req.intr.maxlen =
430 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]),
431 .cb = usbhid_intr_handler_cb,
432 .cb_ctx = sc,
433 .buf = sc->sc_intr_buf,
434 .no_readahead = hid_test_quirk(&sc->sc_hw, HQ_NO_READAHEAD),
435 };
436 sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct usbhid_xfer_ctx) {
437 .req.intr.maxlen =
438 usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]),
439 .cb = usbhid_intr_handler_cb,
440 .cb_ctx = sc,
441 .buf = sc->sc_intr_buf,
442 };
443 usbd_transfer_start(sc->sc_xfer[USBHID_INTR_IN_DT]);
444 if (sc->sc_can_poll)
445 usbd_transfer_start(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
446 mtx_unlock(&sc->sc_mtx);
447
448 return (0);
449 }
450
451 static int
usbhid_intr_stop(device_t dev,device_t child __unused)452 usbhid_intr_stop(device_t dev, device_t child __unused)
453 {
454 struct usbhid_softc* sc = device_get_softc(dev);
455
456 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_IN_DT]);
457 usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_OUT_DT]);
458 if (sc->sc_can_poll)
459 usbd_transfer_drain(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
460
461 return (0);
462 }
463
464 static void
usbhid_intr_poll(device_t dev,device_t child __unused)465 usbhid_intr_poll(device_t dev, device_t child __unused)
466 {
467 struct usbhid_softc* sc = device_get_softc(dev);
468
469 MPASS(sc->sc_can_poll);
470 usbd_transfer_poll(sc->sc_xfer + USBHID_INTR_IN_DT, 1);
471 usbd_transfer_poll(sc->sc_xfer + POLL_XFER(USBHID_INTR_IN_DT), 1);
472 }
473
474 /*
475 * HID interface
476 */
477 static int
usbhid_sync_xfer(struct usbhid_softc * sc,int xfer_idx,union usbhid_device_request * req,void * buf)478 usbhid_sync_xfer(struct usbhid_softc* sc, int xfer_idx,
479 union usbhid_device_request *req, void *buf)
480 {
481 int error, timeout;
482 struct usbhid_xfer_ctx *xfer_ctx;
483
484 xfer_ctx = sc->sc_xfer_ctx + xfer_idx;
485
486 if (USB_IN_POLLING_MODE_FUNC()) {
487 xfer_ctx = POLL_XFER(xfer_ctx);
488 xfer_idx = POLL_XFER(xfer_idx);
489 } else {
490 mtx_lock(&sc->sc_mtx);
491 ++xfer_ctx->waiters;
492 while (xfer_ctx->influx)
493 mtx_sleep(&xfer_ctx->waiters, &sc->sc_mtx, 0,
494 "usbhid wt", 0);
495 --xfer_ctx->waiters;
496 xfer_ctx->influx = true;
497 }
498
499 xfer_ctx->buf = buf;
500 xfer_ctx->req = *req;
501 xfer_ctx->error = ETIMEDOUT;
502 xfer_ctx->cb = &usbhid_sync_wakeup_cb;
503 xfer_ctx->cb_ctx = xfer_ctx;
504 timeout = USB_DEFAULT_TIMEOUT;
505 usbd_transfer_start(sc->sc_xfer[xfer_idx]);
506
507 if (USB_IN_POLLING_MODE_FUNC())
508 while (timeout > 0 && xfer_ctx->error == ETIMEDOUT) {
509 usbd_transfer_poll(sc->sc_xfer + xfer_idx, 1);
510 DELAY(1000);
511 timeout--;
512 }
513 else
514 msleep_sbt(xfer_ctx, &sc->sc_mtx, 0, "usbhid io",
515 SBT_1MS * timeout, 0, C_HARDCLOCK);
516
517 /* Perform usbhid_write() asyncronously to improve pipelining */
518 if (USB_IN_POLLING_MODE_FUNC() || xfer_ctx->error != 0 ||
519 sc->sc_config[xfer_idx].type != UE_INTERRUPT ||
520 sc->sc_config[xfer_idx].direction != UE_DIR_OUT)
521 usbd_transfer_stop(sc->sc_xfer[xfer_idx]);
522 error = xfer_ctx->error;
523 if (error == 0)
524 *req = xfer_ctx->req;
525
526 if (!USB_IN_POLLING_MODE_FUNC()) {
527 xfer_ctx->influx = false;
528 if (xfer_ctx->waiters != 0)
529 wakeup_one(&xfer_ctx->waiters);
530 mtx_unlock(&sc->sc_mtx);
531 }
532
533 if (error)
534 DPRINTF("USB IO error:%d\n", error);
535
536 return (error);
537 }
538
539 static int
usbhid_get_rdesc(device_t dev,device_t child __unused,void * buf,hid_size_t len)540 usbhid_get_rdesc(device_t dev, device_t child __unused, void *buf,
541 hid_size_t len)
542 {
543 struct usbhid_softc* sc = device_get_softc(dev);
544 int error;
545
546 error = usbd_req_get_report_descriptor(sc->sc_udev, NULL,
547 buf, len, sc->sc_iface_index);
548
549 if (error)
550 DPRINTF("no report descriptor: %s\n", usbd_errstr(error));
551
552 return (error == 0 ? 0 : ENXIO);
553 }
554
555 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)556 usbhid_get_report(device_t dev, device_t child __unused, void *buf,
557 hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id)
558 {
559 struct usbhid_softc* sc = device_get_softc(dev);
560 union usbhid_device_request req;
561 int error;
562
563 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, maxlen);
564 if (error)
565 return (error);
566
567 req.ctrl.bmRequestType = UT_READ_CLASS_INTERFACE;
568 req.ctrl.bRequest = UR_GET_REPORT;
569 USETW2(req.ctrl.wValue, type, id);
570 req.ctrl.wIndex[0] = sc->sc_iface_no;
571 req.ctrl.wIndex[1] = 0;
572 USETW(req.ctrl.wLength, maxlen);
573
574 error = usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, buf);
575 if (!error && actlen != NULL)
576 *actlen = maxlen;
577
578 return (error);
579 }
580
581 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)582 usbhid_set_report(device_t dev, device_t child __unused, const void *buf,
583 hid_size_t len, uint8_t type, uint8_t id)
584 {
585 struct usbhid_softc* sc = device_get_softc(dev);
586 union usbhid_device_request req;
587 int error;
588
589 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, len);
590 if (error)
591 return (error);
592
593 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
594 req.ctrl.bRequest = UR_SET_REPORT;
595 USETW2(req.ctrl.wValue, type, id);
596 req.ctrl.wIndex[0] = sc->sc_iface_no;
597 req.ctrl.wIndex[1] = 0;
598 USETW(req.ctrl.wLength, len);
599
600 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req,
601 __DECONST(void *, buf)));
602 }
603
604 static int
usbhid_read(device_t dev,device_t child __unused,void * buf,hid_size_t maxlen,hid_size_t * actlen)605 usbhid_read(device_t dev, device_t child __unused, void *buf,
606 hid_size_t maxlen, hid_size_t *actlen)
607 {
608 struct usbhid_softc* sc = device_get_softc(dev);
609 union usbhid_device_request req;
610 int error;
611
612 error = usbhid_xfer_check_len(sc, USBHID_INTR_IN_DT, maxlen);
613 if (error)
614 return (error);
615
616 req.intr.maxlen = maxlen;
617 error = usbhid_sync_xfer(sc, USBHID_INTR_IN_DT, &req, buf);
618 if (error == 0 && actlen != NULL)
619 *actlen = req.intr.actlen;
620
621 return (error);
622 }
623
624 static int
usbhid_write(device_t dev,device_t child __unused,const void * buf,hid_size_t len)625 usbhid_write(device_t dev, device_t child __unused, const void *buf,
626 hid_size_t len)
627 {
628 struct usbhid_softc* sc = device_get_softc(dev);
629 union usbhid_device_request req;
630 int error;
631
632 error = usbhid_xfer_check_len(sc, USBHID_INTR_OUT_DT, len);
633 if (error)
634 return (error);
635
636 req.intr.maxlen = len;
637 return (usbhid_sync_xfer(sc, USBHID_INTR_OUT_DT, &req,
638 __DECONST(void *, buf)));
639 }
640
641 static int
usbhid_set_idle(device_t dev,device_t child __unused,uint16_t duration,uint8_t id)642 usbhid_set_idle(device_t dev, device_t child __unused, uint16_t duration,
643 uint8_t id)
644 {
645 struct usbhid_softc* sc = device_get_softc(dev);
646 union usbhid_device_request req;
647 int error;
648
649 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
650 if (error)
651 return (error);
652
653 /* Duration is measured in 4 milliseconds per unit. */
654 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
655 req.ctrl.bRequest = UR_SET_IDLE;
656 USETW2(req.ctrl.wValue, (duration + 3) / 4, id);
657 req.ctrl.wIndex[0] = sc->sc_iface_no;
658 req.ctrl.wIndex[1] = 0;
659 USETW(req.ctrl.wLength, 0);
660
661 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
662 }
663
664 static int
usbhid_set_protocol(device_t dev,device_t child __unused,uint16_t protocol)665 usbhid_set_protocol(device_t dev, device_t child __unused, uint16_t protocol)
666 {
667 struct usbhid_softc* sc = device_get_softc(dev);
668 union usbhid_device_request req;
669 int error;
670
671 error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
672 if (error)
673 return (error);
674
675 req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
676 req.ctrl.bRequest = UR_SET_PROTOCOL;
677 USETW(req.ctrl.wValue, protocol);
678 req.ctrl.wIndex[0] = sc->sc_iface_no;
679 req.ctrl.wIndex[1] = 0;
680 USETW(req.ctrl.wLength, 0);
681
682 return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
683 }
684
685 static int
usbhid_ioctl(device_t dev,device_t child __unused,unsigned long cmd,uintptr_t data)686 usbhid_ioctl(device_t dev, device_t child __unused, unsigned long cmd,
687 uintptr_t data)
688 {
689 struct usbhid_softc* sc = device_get_softc(dev);
690 struct usb_ctl_request *ucr;
691 union usbhid_device_request req;
692 int error;
693
694 switch (cmd) {
695 case USB_REQUEST:
696 ucr = (struct usb_ctl_request *)data;
697 req.ctrl = ucr->ucr_request;
698 error = usbhid_xfer_check_len(
699 sc, USBHID_CTRL_DT, UGETW(req.ctrl.wLength));
700 if (error)
701 break;
702 error = usb_check_request(sc->sc_udev, &req.ctrl);
703 if (error)
704 break;
705 error = usbhid_sync_xfer(
706 sc, USBHID_CTRL_DT, &req, ucr->ucr_data);
707 if (error == 0)
708 ucr->ucr_actlen = UGETW(req.ctrl.wLength);
709 break;
710 case USB_GET_DEVICEINFO:
711 error = usbd_fill_deviceinfo(sc->sc_udev,
712 (struct usb_device_info *)data);
713 break;
714 default:
715 error = EINVAL;
716 }
717
718 return (error);
719 }
720
721 static void
usbhid_init_device_info(struct usb_attach_arg * uaa,struct hid_device_info * hw)722 usbhid_init_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
723 {
724
725 hw->idBus = BUS_USB;
726 hw->idVendor = uaa->info.idVendor;
727 hw->idProduct = uaa->info.idProduct;
728 hw->idVersion = uaa->info.bcdDevice;
729
730 /* Set various quirks based on usb_attach_arg */
731 hid_add_dynamic_quirk(hw, USB_GET_DRIVER_INFO(uaa));
732 }
733
734 static void
usbhid_fill_device_info(struct usb_attach_arg * uaa,struct hid_device_info * hw)735 usbhid_fill_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
736 {
737 struct usb_device *udev = uaa->device;
738 struct usb_interface *iface = uaa->iface;
739 struct usb_hid_descriptor *hid;
740 struct usb_endpoint *ep;
741
742 snprintf(hw->name, sizeof(hw->name), "%s %s",
743 usb_get_manufacturer(udev), usb_get_product(udev));
744 strlcpy(hw->serial, usb_get_serial(udev), sizeof(hw->serial));
745
746 if (uaa->info.bInterfaceClass == UICLASS_HID &&
747 iface != NULL && iface->idesc != NULL) {
748 hid = hid_get_descriptor_from_usb(
749 usbd_get_config_descriptor(udev), iface->idesc);
750 if (hid != NULL)
751 hw->rdescsize =
752 UGETW(hid->descrs[0].wDescriptorLength);
753 }
754
755 /* See if there is a interrupt out endpoint. */
756 ep = usbd_get_endpoint(udev, uaa->info.bIfaceIndex,
757 usbhid_config + USBHID_INTR_OUT_DT);
758 if (ep == NULL || ep->methods == NULL)
759 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
760 }
761
762 static const STRUCT_USB_HOST_ID usbhid_devs[] = {
763 /* the Xbox 360 gamepad doesn't use the HID class */
764 {USB_IFACE_CLASS(UICLASS_VENDOR),
765 USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER),
766 USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),
767 USB_DRIVER_INFO(HQ_IS_XBOX360GP)},
768 /* HID keyboard with boot protocol support */
769 {USB_IFACE_CLASS(UICLASS_HID),
770 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
771 USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),
772 USB_DRIVER_INFO(HQ_HAS_KBD_BOOTPROTO)},
773 /* HID mouse with boot protocol support */
774 {USB_IFACE_CLASS(UICLASS_HID),
775 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
776 USB_IFACE_PROTOCOL(UIPROTO_MOUSE),
777 USB_DRIVER_INFO(HQ_HAS_MS_BOOTPROTO)},
778 /* generic HID class */
779 {USB_IFACE_CLASS(UICLASS_HID), USB_DRIVER_INFO(HQ_NONE)},
780 };
781
782 static int
usbhid_probe(device_t dev)783 usbhid_probe(device_t dev)
784 {
785 struct usb_attach_arg *uaa = device_get_ivars(dev);
786 struct usbhid_softc *sc = device_get_softc(dev);
787 int error;
788
789 DPRINTFN(11, "\n");
790
791 if (usbhid_enable == 0)
792 return (ENXIO);
793
794 if (uaa->usb_mode != USB_MODE_HOST)
795 return (ENXIO);
796
797 error = usbd_lookup_id_by_uaa(usbhid_devs, sizeof(usbhid_devs), uaa);
798 if (error)
799 return (error);
800
801 if (usb_test_quirk(uaa, UQ_HID_IGNORE))
802 return (ENXIO);
803
804 /*
805 * Setup temporary hid_device_info so that we can figure out some
806 * basic quirks for this device.
807 */
808 usbhid_init_device_info(uaa, &sc->sc_hw);
809
810 if (hid_test_quirk(&sc->sc_hw, HQ_HID_IGNORE))
811 return (ENXIO);
812
813 return (BUS_PROBE_DEFAULT + 1);
814 }
815
816 static int
usbhid_attach(device_t dev)817 usbhid_attach(device_t dev)
818 {
819 struct usb_attach_arg *uaa = device_get_ivars(dev);
820 struct usbhid_softc *sc = device_get_softc(dev);
821 device_t child;
822 int error = 0;
823
824 DPRINTFN(10, "sc=%p\n", sc);
825
826 device_set_usb_desc(dev);
827
828 sc->sc_udev = uaa->device;
829 sc->sc_iface_no = uaa->info.bIfaceNum;
830 sc->sc_iface_index = uaa->info.bIfaceIndex;
831
832 usbhid_fill_device_info(uaa, &sc->sc_hw);
833
834 error = usbd_req_set_idle(uaa->device, NULL,
835 uaa->info.bIfaceIndex, 0, 0);
836 if (error)
837 DPRINTF("set idle failed, error=%s (ignored)\n",
838 usbd_errstr(error));
839
840 mtx_init(&sc->sc_mtx, "usbhid lock", NULL, MTX_DEF);
841
842 child = device_add_child(dev, "hidbus", DEVICE_UNIT_ANY);
843 if (child == NULL) {
844 device_printf(dev, "Could not add hidbus device\n");
845 usbhid_detach(dev);
846 return (ENOMEM);
847 }
848
849 device_set_ivars(child, &sc->sc_hw);
850 bus_attach_children(dev);
851
852 return (0); /* success */
853 }
854
855 static int
usbhid_detach(device_t dev)856 usbhid_detach(device_t dev)
857 {
858 struct usbhid_softc *sc = device_get_softc(dev);
859 int error;
860
861 error = bus_generic_detach(dev);
862 if (error != 0)
863 return (error);
864
865 mtx_destroy(&sc->sc_mtx);
866
867 return (0);
868 }
869
870 static device_method_t usbhid_methods[] = {
871 DEVMETHOD(device_probe, usbhid_probe),
872 DEVMETHOD(device_attach, usbhid_attach),
873 DEVMETHOD(device_detach, usbhid_detach),
874
875 DEVMETHOD(hid_intr_setup, usbhid_intr_setup),
876 DEVMETHOD(hid_intr_unsetup, usbhid_intr_unsetup),
877 DEVMETHOD(hid_intr_start, usbhid_intr_start),
878 DEVMETHOD(hid_intr_stop, usbhid_intr_stop),
879 DEVMETHOD(hid_intr_poll, usbhid_intr_poll),
880
881 /* HID interface */
882 DEVMETHOD(hid_get_rdesc, usbhid_get_rdesc),
883 DEVMETHOD(hid_read, usbhid_read),
884 DEVMETHOD(hid_write, usbhid_write),
885 DEVMETHOD(hid_get_report, usbhid_get_report),
886 DEVMETHOD(hid_set_report, usbhid_set_report),
887 DEVMETHOD(hid_set_idle, usbhid_set_idle),
888 DEVMETHOD(hid_set_protocol, usbhid_set_protocol),
889 DEVMETHOD(hid_ioctl, usbhid_ioctl),
890
891 DEVMETHOD_END
892 };
893
894 static driver_t usbhid_driver = {
895 .name = "usbhid",
896 .methods = usbhid_methods,
897 .size = sizeof(struct usbhid_softc),
898 };
899
900 DRIVER_MODULE(usbhid, uhub, usbhid_driver, NULL, NULL);
901 MODULE_DEPEND(usbhid, usb, 1, 1, 1);
902 MODULE_DEPEND(usbhid, hid, 1, 1, 1);
903 MODULE_DEPEND(usbhid, hidbus, 1, 1, 1);
904 MODULE_VERSION(usbhid, 1);
905 USB_PNP_HOST_INFO(usbhid_devs);
906