2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
34 #include <sys/epoch.h>
36 #include <sys/kernel.h>
37 #include <sys/libkern.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
43 #include <sys/systm.h>
46 #define HID_DEBUG_VAR hid_debug
47 #include <dev/hid/hid.h>
48 #include <dev/hid/hidbus.h>
49 #include <dev/hid/hidquirk.h>
53 #define INPUT_EPOCH global_epoch_preempt
54 #define HID_RSIZE_MAX 1024
56 static hid_intr_t hidbus_intr;
58 static device_probe_t hidbus_probe;
59 static device_attach_t hidbus_attach;
60 static device_detach_t hidbus_detach;
66 uintptr_t driver_info; /* for internal use */
67 struct mtx *mtx; /* child intr mtx */
68 hid_intr_t *intr_handler; /* executed under mtx*/
70 unsigned int refcnt; /* protected by mtx */
71 struct epoch_context epoch_ctx;
72 CK_STAILQ_ENTRY(hidbus_ivars) link;
82 struct hid_rdesc_info rdesc;
84 int nest; /* Child attach nesting lvl */
85 int nauto; /* Number of autochildren */
87 CK_STAILQ_HEAD(, hidbus_ivars) tlcs;
91 hidbus_fill_rdesc_info(struct hid_rdesc_info *hri, const void *data,
96 hri->data = __DECONST(void *, data);
100 * If report descriptor is not available yet, set maximal
101 * report sizes high enough to allow hidraw to work.
103 hri->isize = len == 0 ? HID_RSIZE_MAX :
104 hid_report_size_max(data, len, hid_input, &hri->iid);
105 hri->osize = len == 0 ? HID_RSIZE_MAX :
106 hid_report_size_max(data, len, hid_output, &hri->oid);
107 hri->fsize = len == 0 ? HID_RSIZE_MAX :
108 hid_report_size_max(data, len, hid_feature, &hri->fid);
110 if (hri->isize > HID_RSIZE_MAX) {
111 DPRINTF("input size is too large, %u bytes (truncating)\n",
113 hri->isize = HID_RSIZE_MAX;
116 if (hri->osize > HID_RSIZE_MAX) {
117 DPRINTF("output size is too large, %u bytes (truncating)\n",
119 hri->osize = HID_RSIZE_MAX;
122 if (hri->fsize > HID_RSIZE_MAX) {
123 DPRINTF("feature size is too large, %u bytes (truncating)\n",
125 hri->fsize = HID_RSIZE_MAX;
133 hidbus_locate(const void *desc, hid_size_t size, int32_t u, enum hid_kind k,
134 uint8_t tlc_index, uint8_t index, struct hid_location *loc,
135 uint32_t *flags, uint8_t *id, struct hid_absinfo *ai)
141 d = hid_start_parse(desc, size, 1 << k);
142 HIDBUS_FOREACH_ITEM(d, &h, tlc_index) {
143 for (i = 0; i < h.nusages; i++) {
144 if (h.kind == k && h.usages[i] == u) {
153 if (ai != NULL && (h.flags&HIO_RELATIVE) == 0)
154 *ai = (struct hid_absinfo) {
155 .max = h.logical_maximum,
156 .min = h.logical_minimum,
157 .res = hid_item_resolution(&h),
175 hidbus_add_child(device_t dev, u_int order, const char *name, int unit)
177 struct hidbus_softc *sc = device_get_softc(dev);
178 struct hidbus_ivars *tlc;
181 child = device_add_child_ordered(dev, order, name, unit);
185 tlc = malloc(sizeof(struct hidbus_ivars), M_DEVBUF, M_WAITOK | M_ZERO);
187 device_set_ivars(child, tlc);
189 CK_STAILQ_INSERT_TAIL(&sc->tlcs, tlc, link);
196 hidbus_enumerate_children(device_t dev, const void* data, hid_size_t len)
198 struct hidbus_softc *sc = device_get_softc(dev);
204 if (data == NULL || len == 0)
207 /* Add a child for each top level collection */
208 hd = hid_start_parse(data, len, 1 << hid_input);
209 while (hid_get_item(hd, &hi)) {
210 if (hi.kind != hid_collection || hi.collevel != 1)
212 child = BUS_ADD_CHILD(dev, 0, NULL, -1);
214 device_printf(dev, "Could not add HID device\n");
217 hidbus_set_index(child, index);
218 hidbus_set_usage(child, hi.usage);
219 hidbus_set_flags(child, HIDBUS_FLAG_AUTOCHILD);
221 DPRINTF("Add child TLC: 0x%04x:0x%04x\n",
222 HID_GET_USAGE_PAGE(hi.usage), HID_GET_USAGE(hi.usage));
235 hidbus_attach_children(device_t dev)
237 struct hidbus_softc *sc = device_get_softc(dev);
240 HID_INTR_SETUP(device_get_parent(dev), hidbus_intr, sc, &sc->rdesc);
242 error = hidbus_enumerate_children(dev, sc->rdesc.data, sc->rdesc.len);
244 DPRINTF("failed to enumerate children: error %d\n", error);
247 * hidbus_attach_children() can recurse through device_identify->
248 * hid_set_report_descr() call sequence. Do not perform children
249 * attach twice in that case.
252 bus_generic_probe(dev);
257 if (hid_is_keyboard(sc->rdesc.data, sc->rdesc.len) != 0)
258 error = bus_generic_attach(dev);
260 error = bus_delayed_attach_children(dev);
262 device_printf(dev, "failed to attach child: error %d\n", error);
268 hidbus_detach_children(device_t dev)
270 device_t *children, bus;
276 is_bus = device_get_devclass(dev) == hidbus_devclass;
277 bus = is_bus ? dev : device_get_parent(dev);
279 KASSERT(device_get_devclass(bus) == hidbus_devclass,
280 ("Device is not hidbus or it's child"));
283 /* If hidbus is passed, delete all children. */
284 bus_generic_detach(bus);
285 device_delete_children(bus);
288 * If hidbus child is passed, delete all hidbus children
289 * except caller. Deleting the caller may result in deadlock.
291 error = device_get_children(bus, &children, &i);
295 if (children[i] == dev)
297 DPRINTF("Delete child. index=%d (%s)\n",
298 hidbus_get_index(children[i]),
299 device_get_nameunit(children[i]));
300 error = device_delete_child(bus, children[i]);
302 DPRINTF("Failed deleting %s\n",
303 device_get_nameunit(children[i]));
307 free(children, M_TEMP);
310 HID_INTR_UNSETUP(device_get_parent(bus));
316 hidbus_probe(device_t dev)
319 device_set_desc(dev, "HID bus");
321 /* Allow other subclasses to override this driver. */
322 return (BUS_PROBE_GENERIC);
326 hidbus_attach(device_t dev)
328 struct hidbus_softc *sc = device_get_softc(dev);
329 struct hid_device_info *devinfo = device_get_ivars(dev);
335 CK_STAILQ_INIT(&sc->tlcs);
336 mtx_init(&sc->mtx, "hidbus ivar lock", NULL, MTX_DEF);
337 sx_init(&sc->sx, "hidbus ivar list lock");
340 * Ignore error. It is possible for non-HID device e.g. XBox360 gamepad
341 * to emulate HID through overloading of report descriptor.
343 d_len = devinfo->rdescsize;
345 d_ptr = malloc(d_len, M_DEVBUF, M_ZERO | M_WAITOK);
346 error = hid_get_rdesc(dev, d_ptr, d_len);
348 free(d_ptr, M_DEVBUF);
354 hidbus_fill_rdesc_info(&sc->rdesc, d_ptr, d_len);
356 sc->nowrite = hid_test_quirk(devinfo, HQ_NOWRITE);
358 error = hidbus_attach_children(dev);
368 hidbus_detach(device_t dev)
370 struct hidbus_softc *sc = device_get_softc(dev);
372 hidbus_detach_children(dev);
374 mtx_destroy(&sc->mtx);
375 free(sc->rdesc.data, M_DEVBUF);
381 hidbus_child_detached(device_t bus, device_t child)
383 struct hidbus_softc *sc = device_get_softc(bus);
384 struct hidbus_ivars *tlc = device_get_ivars(child);
386 KASSERT(tlc->refcnt == 0, ("Child device is running"));
388 tlc->intr_handler = NULL;
389 tlc->flags &= ~HIDBUS_FLAG_CAN_POLL;
393 * Epoch callback indicating tlc is safe to destroy
396 hidbus_ivar_dtor(epoch_context_t ctx)
398 struct hidbus_ivars *tlc;
400 tlc = __containerof(ctx, struct hidbus_ivars, epoch_ctx);
405 hidbus_child_deleted(device_t bus, device_t child)
407 struct hidbus_softc *sc = device_get_softc(bus);
408 struct hidbus_ivars *tlc = device_get_ivars(child);
411 KASSERT(tlc->refcnt == 0, ("Child device is running"));
412 CK_STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link);
414 epoch_call(INPUT_EPOCH, hidbus_ivar_dtor, &tlc->epoch_ctx);
418 hidbus_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
420 struct hidbus_softc *sc = device_get_softc(bus);
421 struct hidbus_ivars *tlc = device_get_ivars(child);
424 case HIDBUS_IVAR_INDEX:
425 *result = tlc->index;
427 case HIDBUS_IVAR_USAGE:
428 *result = tlc->usage;
430 case HIDBUS_IVAR_FLAGS:
431 *result = tlc->flags;
433 case HIDBUS_IVAR_DRIVER_INFO:
434 *result = tlc->driver_info;
436 case HIDBUS_IVAR_LOCK:
437 *result = (uintptr_t)(tlc->mtx == &sc->mtx ? NULL : tlc->mtx);
446 hidbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
448 struct hidbus_softc *sc = device_get_softc(bus);
449 struct hidbus_ivars *tlc = device_get_ivars(child);
452 case HIDBUS_IVAR_INDEX:
455 case HIDBUS_IVAR_USAGE:
458 case HIDBUS_IVAR_FLAGS:
461 case HIDBUS_IVAR_DRIVER_INFO:
462 tlc->driver_info = value;
464 case HIDBUS_IVAR_LOCK:
465 tlc->mtx = (struct mtx *)value == NULL ?
466 &sc->mtx : (struct mtx *)value;
474 /* Location hint for devctl(8) */
476 hidbus_child_location_str(device_t bus, device_t child, char *buf,
479 struct hidbus_ivars *tlc = device_get_ivars(child);
481 snprintf(buf, buflen, "index=%hhu", tlc->index);
485 /* PnP information for devctl(8) */
487 hidbus_child_pnpinfo_str(device_t bus, device_t child, char *buf,
490 struct hidbus_ivars *tlc = device_get_ivars(child);
491 struct hid_device_info *devinfo = device_get_ivars(bus);
493 snprintf(buf, buflen, "page=0x%04x usage=0x%04x bus=0x%02hx "
494 "vendor=0x%04hx product=0x%04hx version=0x%04hx%s%s",
495 HID_GET_USAGE_PAGE(tlc->usage), HID_GET_USAGE(tlc->usage),
496 devinfo->idBus, devinfo->idVendor, devinfo->idProduct,
497 devinfo->idVersion, devinfo->idPnP[0] == '\0' ? "" : " _HID=",
498 devinfo->idPnP[0] == '\0' ? "" : devinfo->idPnP);
503 hidbus_set_desc(device_t child, const char *suffix)
505 device_t bus = device_get_parent(child);
506 struct hidbus_softc *sc = device_get_softc(bus);
507 struct hid_device_info *devinfo = device_get_ivars(bus);
508 struct hidbus_ivars *tlc = device_get_ivars(child);
511 /* Do not add NULL suffix or if device name already contains it. */
512 if (suffix != NULL && strcasestr(devinfo->name, suffix) == NULL &&
513 (sc->nauto > 1 || (tlc->flags & HIDBUS_FLAG_AUTOCHILD) == 0)) {
514 snprintf(buf, sizeof(buf), "%s %s", devinfo->name, suffix);
515 device_set_desc_copy(child, buf);
517 device_set_desc(child, devinfo->name);
521 hidbus_find_child(device_t bus, int32_t usage)
523 device_t *children, child;
528 /* Get a list of all hidbus children */
529 if (device_get_children(bus, &children, &ccount) != 0)
532 /* Scan through to find required TLC */
533 for (i = 0, child = NULL; i < ccount; i++) {
534 if (hidbus_get_usage(children[i]) == usage) {
539 free(children, M_TEMP);
545 hidbus_intr(void *context, void *buf, hid_size_t len)
547 struct hidbus_softc *sc = context;
548 struct hidbus_ivars *tlc;
549 struct epoch_tracker et;
552 * Broadcast input report to all subscribers.
553 * TODO: Add check for input report ID.
555 * Relock mutex on every TLC item as we can't hold any locks over whole
556 * TLC list here due to LOR with open()/close() handlers.
558 if (!HID_IN_POLLING_MODE())
559 epoch_enter_preempt(INPUT_EPOCH, &et);
560 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
561 if (tlc->refcnt == 0 || tlc->intr_handler == NULL)
563 if (HID_IN_POLLING_MODE()) {
564 if ((tlc->flags & HIDBUS_FLAG_CAN_POLL) != 0)
565 tlc->intr_handler(tlc->intr_ctx, buf, len);
568 tlc->intr_handler(tlc->intr_ctx, buf, len);
569 mtx_unlock(tlc->mtx);
572 if (!HID_IN_POLLING_MODE())
573 epoch_exit_preempt(INPUT_EPOCH, &et);
577 hidbus_set_intr(device_t child, hid_intr_t *handler, void *context)
579 struct hidbus_ivars *tlc = device_get_ivars(child);
581 tlc->intr_handler = handler;
582 tlc->intr_ctx = context;
586 hidbus_intr_start(device_t child)
588 device_t bus = device_get_parent(child);
589 struct hidbus_softc *sc = device_get_softc(bus);
590 struct hidbus_ivars *ivar = device_get_ivars(child);
591 struct hidbus_ivars *tlc;
595 if (sx_xlock_sig(&sc->sx) != 0)
597 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
598 refcnt += tlc->refcnt;
602 mtx_unlock(tlc->mtx);
605 error = refcnt != 0 ? 0 : HID_INTR_START(device_get_parent(bus));
612 hidbus_intr_stop(device_t child)
614 device_t bus = device_get_parent(child);
615 struct hidbus_softc *sc = device_get_softc(bus);
616 struct hidbus_ivars *ivar = device_get_ivars(child);
617 struct hidbus_ivars *tlc;
621 if (sx_xlock_sig(&sc->sx) != 0)
623 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) {
626 MPASS(tlc->refcnt != 0);
628 mtx_unlock(tlc->mtx);
630 refcnt += tlc->refcnt;
632 error = refcnt != 0 ? 0 : HID_INTR_STOP(device_get_parent(bus));
639 hidbus_intr_poll(device_t child)
641 device_t bus = device_get_parent(child);
643 HID_INTR_POLL(device_get_parent(bus));
646 struct hid_rdesc_info *
647 hidbus_get_rdesc_info(device_t child)
649 device_t bus = device_get_parent(child);
650 struct hidbus_softc *sc = device_get_softc(bus);
658 * Hidbus as well as any hidbus child can be passed as first arg.
661 /* Read cached report descriptor */
663 hid_get_report_descr(device_t dev, void **data, hid_size_t *len)
666 struct hidbus_softc *sc;
668 bus = device_get_devclass(dev) == hidbus_devclass ?
669 dev : device_get_parent(dev);
670 sc = device_get_softc(bus);
673 * Do not send request to a transport backend.
674 * Use cached report descriptor instead of it.
676 if (sc->rdesc.data == NULL || sc->rdesc.len == 0)
680 *data = sc->rdesc.data;
682 *len = sc->rdesc.len;
688 * Replace cached report descriptor with top level driver provided one.
690 * It deletes all hidbus children except caller and enumerates them again after
691 * new descriptor has been registered. Currently it can not be called from
692 * autoenumerated (by report's TLC) child device context as it results in child
693 * duplication. To overcome this limitation hid_set_report_descr() should be
694 * called from device_identify driver's handler with hidbus itself passed as
695 * 'device_t dev' parameter.
698 hid_set_report_descr(device_t dev, const void *data, hid_size_t len)
700 struct hid_rdesc_info rdesc;
702 struct hidbus_softc *sc;
708 is_bus = device_get_devclass(dev) == hidbus_devclass;
709 bus = is_bus ? dev : device_get_parent(dev);
710 sc = device_get_softc(bus);
713 * Do not overload already overloaded report descriptor in
714 * device_identify handler. It causes infinite recursion loop.
716 if (is_bus && sc->overloaded)
719 DPRINTFN(5, "len=%d\n", len);
720 DPRINTFN(5, "data = %*D\n", len, data, " ");
722 error = hidbus_fill_rdesc_info(&rdesc, data, len);
726 error = hidbus_detach_children(dev);
730 /* Make private copy to handle a case of dynamicaly allocated data. */
731 rdesc.data = malloc(len, M_DEVBUF, M_ZERO | M_WAITOK);
732 bcopy(data, rdesc.data, len);
733 sc->overloaded = true;
734 free(sc->rdesc.data, M_DEVBUF);
735 bcopy(&rdesc, &sc->rdesc, sizeof(struct hid_rdesc_info));
737 error = hidbus_attach_children(bus);
743 hidbus_write(device_t dev, const void *data, hid_size_t len)
745 struct hidbus_softc *sc;
748 sc = device_get_softc(dev);
750 * Output interrupt endpoint is often optional. If HID device
751 * does not provide it, send reports via control pipe.
754 /* try to extract the ID byte */
755 id = (sc->rdesc.oid & (len > 0)) ? *(const uint8_t*)data : 0;
756 return (hid_set_report(dev, data, len, HID_OUTPUT_REPORT, id));
759 return (hid_write(dev, data, len));
762 /*------------------------------------------------------------------------*
765 * This functions takes an array of "struct hid_device_id" and tries
766 * to match the entries with the information in "struct hid_device_info".
769 * NULL: No match found.
770 * Else: Pointer to matching entry.
771 *------------------------------------------------------------------------*/
772 const struct hid_device_id *
773 hidbus_lookup_id(device_t dev, const struct hid_device_id *id, int nitems_id)
775 const struct hid_device_id *id_end;
776 const struct hid_device_info *info;
784 id_end = id + nitems_id;
785 info = hid_get_device_info(dev);
786 is_child = device_get_devclass(dev) != hidbus_devclass;
788 usage = hidbus_get_usage(dev);
791 * Keep on matching array entries until we find a match or
792 * until we reach the end of the matching array:
794 for (; id != id_end; id++) {
796 if (is_child && (id->match_flag_page) &&
797 (id->page != HID_GET_USAGE_PAGE(usage))) {
800 if (is_child && (id->match_flag_usage) &&
801 (id->usage != HID_GET_USAGE(usage))) {
804 if ((id->match_flag_bus) &&
805 (id->idBus != info->idBus)) {
808 if ((id->match_flag_vendor) &&
809 (id->idVendor != info->idVendor)) {
812 if ((id->match_flag_product) &&
813 (id->idProduct != info->idProduct)) {
816 if ((id->match_flag_ver_lo) &&
817 (id->idVersion_lo > info->idVersion)) {
820 if ((id->match_flag_ver_hi) &&
821 (id->idVersion_hi < info->idVersion)) {
824 if (id->match_flag_pnp &&
825 strncmp(id->idPnP, info->idPnP, HID_PNP_ID_SIZE) != 0) {
828 /* We found a match! */
836 /*------------------------------------------------------------------------*
837 * hidbus_lookup_driver_info - factored out code
842 *------------------------------------------------------------------------*/
844 hidbus_lookup_driver_info(device_t child, const struct hid_device_id *id,
848 id = hidbus_lookup_id(child, id, nitems_id);
850 /* copy driver info */
851 hidbus_set_driver_info(child, id->driver_info);
857 const struct hid_device_info *
858 hid_get_device_info(device_t dev)
862 bus = device_get_devclass(dev) == hidbus_devclass ?
863 dev : device_get_parent(dev);
865 return (device_get_ivars(bus));
868 static device_method_t hidbus_methods[] = {
869 /* device interface */
870 DEVMETHOD(device_probe, hidbus_probe),
871 DEVMETHOD(device_attach, hidbus_attach),
872 DEVMETHOD(device_detach, hidbus_detach),
873 DEVMETHOD(device_suspend, bus_generic_suspend),
874 DEVMETHOD(device_resume, bus_generic_resume),
877 DEVMETHOD(bus_add_child, hidbus_add_child),
878 DEVMETHOD(bus_child_detached, hidbus_child_detached),
879 DEVMETHOD(bus_child_deleted, hidbus_child_deleted),
880 DEVMETHOD(bus_read_ivar, hidbus_read_ivar),
881 DEVMETHOD(bus_write_ivar, hidbus_write_ivar),
882 DEVMETHOD(bus_child_pnpinfo_str,hidbus_child_pnpinfo_str),
883 DEVMETHOD(bus_child_location_str,hidbus_child_location_str),
886 DEVMETHOD(hid_get_rdesc, hid_get_rdesc),
887 DEVMETHOD(hid_read, hid_read),
888 DEVMETHOD(hid_write, hidbus_write),
889 DEVMETHOD(hid_get_report, hid_get_report),
890 DEVMETHOD(hid_set_report, hid_set_report),
891 DEVMETHOD(hid_set_idle, hid_set_idle),
892 DEVMETHOD(hid_set_protocol, hid_set_protocol),
897 devclass_t hidbus_devclass;
898 driver_t hidbus_driver = {
901 sizeof(struct hidbus_softc),
904 MODULE_DEPEND(hidbus, hid, 1, 1, 1);
905 MODULE_VERSION(hidbus, 1);
906 DRIVER_MODULE(hidbus, iichid, hidbus_driver, hidbus_devclass, 0, 0);
907 DRIVER_MODULE(hidbus, usbhid, hidbus_driver, hidbus_devclass, 0, 0);