]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/usb/input/usbhid.c
contrib/tzdata: import tzdata 2021b
[FreeBSD/FreeBSD.git] / sys / dev / usb / input / usbhid.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-NetBSD
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 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 /*
37  * HID spec: https://www.usb.org/sites/default/files/documents/hid1_11.pdf
38  */
39
40 #include <sys/stdint.h>
41 #include <sys/stddef.h>
42 #include <sys/param.h>
43 #include <sys/queue.h>
44 #include <sys/types.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/bus.h>
48 #include <sys/module.h>
49 #include <sys/lock.h>
50 #include <sys/mutex.h>
51 #include <sys/condvar.h>
52 #include <sys/sysctl.h>
53 #include <sys/sx.h>
54 #include <sys/unistd.h>
55 #include <sys/callout.h>
56 #include <sys/malloc.h>
57 #include <sys/priv.h>
58 #include <sys/conf.h>
59 #include <sys/fcntl.h>
60
61 #include <dev/evdev/input.h>
62
63 #include <dev/hid/hid.h>
64 #include <dev/hid/hidquirk.h>
65
66 #include <dev/usb/usb.h>
67 #include <dev/usb/usbdi.h>
68 #include <dev/usb/usbdi_util.h>
69 #include <dev/usb/usbhid.h>
70 #include <dev/usb/usb_core.h>
71
72 #define USB_DEBUG_VAR usbhid_debug
73 #include <dev/usb/usb_debug.h>
74
75 #include <dev/usb/quirk/usb_quirk.h>
76
77 #include "hid_if.h"
78
79 static SYSCTL_NODE(_hw_usb, OID_AUTO, usbhid, CTLFLAG_RW, 0, "USB usbhid");
80 static int usbhid_enable = 0;
81 SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, enable, CTLFLAG_RWTUN,
82     &usbhid_enable, 0, "Enable usbhid and prefer it to other USB HID drivers");
83 #ifdef USB_DEBUG
84 static int usbhid_debug = 0;
85 SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, debug, CTLFLAG_RWTUN,
86     &usbhid_debug, 0, "Debug level");
87 #endif
88
89 /* Second set of USB transfers for polling mode */
90 #define POLL_XFER(xfer) ((xfer) + USBHID_N_TRANSFER)
91 enum {
92         USBHID_INTR_OUT_DT,
93         USBHID_INTR_IN_DT,
94         USBHID_CTRL_DT,
95         USBHID_N_TRANSFER,
96 };
97
98 struct usbhid_xfer_ctx;
99 typedef int usbhid_callback_t(struct usbhid_xfer_ctx *xfer_ctx);
100
101 union usbhid_device_request {
102         struct {                        /* INTR xfers */
103                 uint16_t maxlen;
104                 uint16_t actlen;
105         } intr;
106         struct usb_device_request ctrl; /* CTRL xfers */
107 };
108
109 /* Syncronous USB transfer context */
110 struct usbhid_xfer_ctx {
111         union usbhid_device_request req;
112         uint8_t *buf;
113         int error;
114         usbhid_callback_t *cb;
115         void *cb_ctx;
116         int waiters;
117         bool influx;
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
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
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
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
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 (0);
277 }
278
279 static int
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
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
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
334 usbhid_intr_setup(device_t dev, hid_intr_t intr, void *context,
335     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
407 usbhid_intr_unsetup(device_t dev)
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
420 usbhid_intr_start(device_t dev)
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         };
435         sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct usbhid_xfer_ctx) {
436                 .req.intr.maxlen =
437                     usbd_xfer_max_len(sc->sc_xfer[USBHID_INTR_IN_DT]),
438                 .cb = usbhid_intr_handler_cb,
439                 .cb_ctx = sc,
440                 .buf = sc->sc_intr_buf,
441         };
442         usbd_transfer_start(sc->sc_xfer[USBHID_INTR_IN_DT]);
443         if (sc->sc_can_poll)
444                 usbd_transfer_start(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
445         mtx_unlock(&sc->sc_mtx);
446
447         return (0);
448 }
449
450 static int
451 usbhid_intr_stop(device_t dev)
452 {
453         struct usbhid_softc* sc = device_get_softc(dev);
454
455         usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_IN_DT]);
456         usbd_transfer_drain(sc->sc_xfer[USBHID_INTR_OUT_DT]);
457         if (sc->sc_can_poll)
458                 usbd_transfer_drain(sc->sc_xfer[POLL_XFER(USBHID_INTR_IN_DT)]);
459
460         return (0);
461 }
462
463 static void
464 usbhid_intr_poll(device_t dev)
465 {
466         struct usbhid_softc* sc = device_get_softc(dev);
467
468         MPASS(sc->sc_can_poll);
469         usbd_transfer_poll(sc->sc_xfer + USBHID_INTR_IN_DT, 1);
470         usbd_transfer_poll(sc->sc_xfer + POLL_XFER(USBHID_INTR_IN_DT), 1);
471 }
472
473 /*
474  * HID interface
475  */
476 static int
477 usbhid_sync_xfer(struct usbhid_softc* sc, int xfer_idx,
478     union usbhid_device_request *req, void *buf)
479 {
480         int error, timeout;
481         struct usbhid_xfer_ctx *xfer_ctx;
482
483         xfer_ctx = sc->sc_xfer_ctx + xfer_idx;
484
485         if (USB_IN_POLLING_MODE_FUNC()) {
486                 xfer_ctx = POLL_XFER(xfer_ctx);
487                 xfer_idx = POLL_XFER(xfer_idx);
488         } else {
489                 mtx_lock(&sc->sc_mtx);
490                 ++xfer_ctx->waiters;
491                 while (xfer_ctx->influx)
492                         mtx_sleep(&xfer_ctx->waiters, &sc->sc_mtx, 0,
493                             "usbhid wt", 0);
494                 --xfer_ctx->waiters;
495                 xfer_ctx->influx = true;
496         }
497
498         xfer_ctx->buf = buf;
499         xfer_ctx->req = *req;
500         xfer_ctx->error = ETIMEDOUT;
501         xfer_ctx->cb = &usbhid_sync_wakeup_cb;
502         xfer_ctx->cb_ctx = xfer_ctx;
503         timeout = USB_DEFAULT_TIMEOUT;
504         usbd_transfer_start(sc->sc_xfer[xfer_idx]);
505
506         if (USB_IN_POLLING_MODE_FUNC())
507                 while (timeout > 0 && xfer_ctx->error == ETIMEDOUT) {
508                         usbd_transfer_poll(sc->sc_xfer + xfer_idx, 1);
509                         DELAY(1000);
510                         timeout--;
511                 }
512          else
513                 msleep_sbt(xfer_ctx, &sc->sc_mtx, 0, "usbhid io",
514                     SBT_1MS * timeout, 0, C_HARDCLOCK);
515
516         /* Perform usbhid_write() asyncronously to improve pipelining */
517         if (USB_IN_POLLING_MODE_FUNC() || xfer_ctx->error != 0 ||
518             sc->sc_config[xfer_idx].type != UE_INTERRUPT ||
519             sc->sc_config[xfer_idx].direction != UE_DIR_OUT)
520                 usbd_transfer_stop(sc->sc_xfer[xfer_idx]);
521         error = xfer_ctx->error;
522         if (error == 0)
523                 *req = xfer_ctx->req;
524
525         if (!USB_IN_POLLING_MODE_FUNC()) {
526                 xfer_ctx->influx = false;
527                 if (xfer_ctx->waiters != 0)
528                         wakeup_one(&xfer_ctx->waiters);
529                 mtx_unlock(&sc->sc_mtx);
530         }
531
532         if (error)
533                 DPRINTF("USB IO error:%d\n", error);
534
535         return (error);
536 }
537
538 static int
539 usbhid_get_rdesc(device_t dev, void *buf, 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
554 usbhid_get_report(device_t dev, void *buf, hid_size_t maxlen,
555     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
580 usbhid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type,
581     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
603 usbhid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen)
604 {
605         struct usbhid_softc* sc = device_get_softc(dev);
606         union usbhid_device_request req;
607         int error;
608
609         error = usbhid_xfer_check_len(sc, USBHID_INTR_IN_DT, maxlen);
610         if (error)
611                 return (error);
612
613         req.intr.maxlen = maxlen;
614         error = usbhid_sync_xfer(sc, USBHID_INTR_IN_DT, &req, buf);
615         if (error == 0 && actlen != NULL)
616                 *actlen = req.intr.actlen;
617
618         return (error);
619 }
620
621 static int
622 usbhid_write(device_t dev, const void *buf, hid_size_t len)
623 {
624         struct usbhid_softc* sc = device_get_softc(dev);
625         union usbhid_device_request req;
626         int error;
627
628         error = usbhid_xfer_check_len(sc, USBHID_INTR_OUT_DT, len);
629         if (error)
630                 return (error);
631
632         req.intr.maxlen = len;
633         return (usbhid_sync_xfer(sc, USBHID_INTR_OUT_DT, &req,
634             __DECONST(void *, buf)));
635 }
636
637 static int
638 usbhid_set_idle(device_t dev, uint16_t duration, uint8_t id)
639 {
640         struct usbhid_softc* sc = device_get_softc(dev);
641         union usbhid_device_request req;
642         int error;
643
644         error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
645         if (error)
646                 return (error);
647
648         /* Duration is measured in 4 milliseconds per unit. */
649         req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
650         req.ctrl.bRequest = UR_SET_IDLE;
651         USETW2(req.ctrl.wValue, (duration + 3) / 4, id);
652         req.ctrl.wIndex[0] = sc->sc_iface_no;
653         req.ctrl.wIndex[1] = 0;
654         USETW(req.ctrl.wLength, 0);
655
656         return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
657 }
658
659 static int
660 usbhid_set_protocol(device_t dev, uint16_t protocol)
661 {
662         struct usbhid_softc* sc = device_get_softc(dev);
663         union usbhid_device_request req;
664         int error;
665
666         error = usbhid_xfer_check_len(sc, USBHID_CTRL_DT, 0);
667         if (error)
668                 return (error);
669
670         req.ctrl.bmRequestType = UT_WRITE_CLASS_INTERFACE;
671         req.ctrl.bRequest = UR_SET_PROTOCOL;
672         USETW(req.ctrl.wValue, protocol);
673         req.ctrl.wIndex[0] = sc->sc_iface_no;
674         req.ctrl.wIndex[1] = 0;
675         USETW(req.ctrl.wLength, 0);
676
677         return (usbhid_sync_xfer(sc, USBHID_CTRL_DT, &req, NULL));
678 }
679
680 static void
681 usbhid_init_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
682 {
683
684         hw->idBus = BUS_USB;
685         hw->idVendor = uaa->info.idVendor;
686         hw->idProduct = uaa->info.idProduct;
687         hw->idVersion = uaa->info.bcdDevice;
688
689         /* Set various quirks based on usb_attach_arg */
690         hid_add_dynamic_quirk(hw, USB_GET_DRIVER_INFO(uaa));
691 }
692
693 static void
694 usbhid_fill_device_info(struct usb_attach_arg *uaa, struct hid_device_info *hw)
695 {
696         struct usb_device *udev = uaa->device;
697         struct usb_interface *iface = uaa->iface;
698         struct usb_hid_descriptor *hid;
699         struct usb_endpoint *ep;
700
701         snprintf(hw->name, sizeof(hw->name), "%s %s",
702             usb_get_manufacturer(udev), usb_get_product(udev));
703         strlcpy(hw->serial, usb_get_serial(udev), sizeof(hw->serial));
704
705         if (uaa->info.bInterfaceClass == UICLASS_HID &&
706             iface != NULL && iface->idesc != NULL) {
707                 hid = hid_get_descriptor_from_usb(
708                     usbd_get_config_descriptor(udev), iface->idesc);
709                 if (hid != NULL)
710                         hw->rdescsize =
711                             UGETW(hid->descrs[0].wDescriptorLength);
712         }
713
714         /* See if there is a interrupt out endpoint. */
715         ep = usbd_get_endpoint(udev, uaa->info.bIfaceIndex,
716             usbhid_config + USBHID_INTR_OUT_DT);
717         if (ep == NULL || ep->methods == NULL)
718                 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
719 }
720
721 static const STRUCT_USB_HOST_ID usbhid_devs[] = {
722         /* the Xbox 360 gamepad doesn't use the HID class */
723         {USB_IFACE_CLASS(UICLASS_VENDOR),
724          USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER),
725          USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),
726          USB_DRIVER_INFO(HQ_IS_XBOX360GP)},
727         /* HID keyboard with boot protocol support */
728         {USB_IFACE_CLASS(UICLASS_HID),
729          USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
730          USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),
731          USB_DRIVER_INFO(HQ_HAS_KBD_BOOTPROTO)},
732         /* HID mouse with boot protocol support */
733         {USB_IFACE_CLASS(UICLASS_HID),
734          USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
735          USB_IFACE_PROTOCOL(UIPROTO_MOUSE),
736          USB_DRIVER_INFO(HQ_HAS_MS_BOOTPROTO)},
737         /* generic HID class */
738         {USB_IFACE_CLASS(UICLASS_HID), USB_DRIVER_INFO(HQ_NONE)},
739 };
740
741 static int
742 usbhid_probe(device_t dev)
743 {
744         struct usb_attach_arg *uaa = device_get_ivars(dev);
745         struct usbhid_softc *sc = device_get_softc(dev);
746         int error;
747
748         DPRINTFN(11, "\n");
749
750         if (usbhid_enable == 0)
751                 return (ENXIO);
752
753         if (uaa->usb_mode != USB_MODE_HOST)
754                 return (ENXIO);
755
756         error = usbd_lookup_id_by_uaa(usbhid_devs, sizeof(usbhid_devs), uaa);
757         if (error)
758                 return (error);
759
760         if (usb_test_quirk(uaa, UQ_HID_IGNORE))
761                 return (ENXIO);
762
763         /*
764          * Setup temporary hid_device_info so that we can figure out some
765          * basic quirks for this device.
766          */
767         usbhid_init_device_info(uaa, &sc->sc_hw);
768
769         if (hid_test_quirk(&sc->sc_hw, HQ_HID_IGNORE))
770                 return (ENXIO);
771
772         return (BUS_PROBE_GENERIC + 1);
773 }
774
775 static int
776 usbhid_attach(device_t dev)
777 {
778         struct usb_attach_arg *uaa = device_get_ivars(dev);
779         struct usbhid_softc *sc = device_get_softc(dev);
780         device_t child;
781         int error = 0;
782
783         DPRINTFN(10, "sc=%p\n", sc);
784
785         device_set_usb_desc(dev);
786
787         sc->sc_udev = uaa->device;
788         sc->sc_iface_no = uaa->info.bIfaceNum;
789         sc->sc_iface_index = uaa->info.bIfaceIndex;
790
791         usbhid_fill_device_info(uaa, &sc->sc_hw);
792
793         error = usbd_req_set_idle(uaa->device, NULL,
794             uaa->info.bIfaceIndex, 0, 0);
795         if (error)
796                 DPRINTF("set idle failed, error=%s (ignored)\n",
797                     usbd_errstr(error));
798
799         mtx_init(&sc->sc_mtx, "usbhid lock", NULL, MTX_DEF);
800
801         child = device_add_child(dev, "hidbus", -1);
802         if (child == NULL) {
803                 device_printf(dev, "Could not add hidbus device\n");
804                 usbhid_detach(dev);
805                 return (ENOMEM);
806         }
807
808         device_set_ivars(child, &sc->sc_hw);
809         error = bus_generic_attach(dev);
810         if (error) {
811                 device_printf(dev, "failed to attach child: %d\n", error);
812                 usbhid_detach(dev);
813                 return (error);
814         }
815
816         return (0);                     /* success */
817 }
818
819 static int
820 usbhid_detach(device_t dev)
821 {
822         struct usbhid_softc *sc = device_get_softc(dev);
823
824         device_delete_children(dev);
825         mtx_destroy(&sc->sc_mtx);
826
827         return (0);
828 }
829
830 static devclass_t usbhid_devclass;
831
832 static device_method_t usbhid_methods[] = {
833         DEVMETHOD(device_probe,         usbhid_probe),
834         DEVMETHOD(device_attach,        usbhid_attach),
835         DEVMETHOD(device_detach,        usbhid_detach),
836
837         DEVMETHOD(hid_intr_setup,       usbhid_intr_setup),
838         DEVMETHOD(hid_intr_unsetup,     usbhid_intr_unsetup),
839         DEVMETHOD(hid_intr_start,       usbhid_intr_start),
840         DEVMETHOD(hid_intr_stop,        usbhid_intr_stop),
841         DEVMETHOD(hid_intr_poll,        usbhid_intr_poll),
842
843         /* HID interface */
844         DEVMETHOD(hid_get_rdesc,        usbhid_get_rdesc),
845         DEVMETHOD(hid_read,             usbhid_read),
846         DEVMETHOD(hid_write,            usbhid_write),
847         DEVMETHOD(hid_get_report,       usbhid_get_report),
848         DEVMETHOD(hid_set_report,       usbhid_set_report),
849         DEVMETHOD(hid_set_idle,         usbhid_set_idle),
850         DEVMETHOD(hid_set_protocol,     usbhid_set_protocol),
851
852         DEVMETHOD_END
853 };
854
855 static driver_t usbhid_driver = {
856         .name = "usbhid",
857         .methods = usbhid_methods,
858         .size = sizeof(struct usbhid_softc),
859 };
860
861 DRIVER_MODULE(usbhid, uhub, usbhid_driver, usbhid_devclass, NULL, 0);
862 MODULE_DEPEND(usbhid, usb, 1, 1, 1);
863 MODULE_DEPEND(usbhid, hid, 1, 1, 1);
864 MODULE_DEPEND(usbhid, hidbus, 1, 1, 1);
865 MODULE_VERSION(usbhid, 1);
866 USB_PNP_HOST_INFO(usbhid_devs);