Lines Matching +full:bus +full:- +full:id

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
29 #include <sys/bus.h>
94 hri->data = __DECONST(void *, data); in hidbus_fill_rdesc_info()
95 hri->len = len; in hidbus_fill_rdesc_info()
101 hri->isize = len == 0 ? HID_RSIZE_MAX : in hidbus_fill_rdesc_info()
102 hid_report_size_max(data, len, hid_input, &hri->iid); in hidbus_fill_rdesc_info()
103 hri->osize = len == 0 ? HID_RSIZE_MAX : in hidbus_fill_rdesc_info()
104 hid_report_size_max(data, len, hid_output, &hri->oid); in hidbus_fill_rdesc_info()
105 hri->fsize = len == 0 ? HID_RSIZE_MAX : in hidbus_fill_rdesc_info()
106 hid_report_size_max(data, len, hid_feature, &hri->fid); in hidbus_fill_rdesc_info()
108 if (hri->isize > HID_RSIZE_MAX) { in hidbus_fill_rdesc_info()
110 hri->isize); in hidbus_fill_rdesc_info()
111 hri->isize = HID_RSIZE_MAX; in hidbus_fill_rdesc_info()
114 if (hri->osize > HID_RSIZE_MAX) { in hidbus_fill_rdesc_info()
116 hri->osize); in hidbus_fill_rdesc_info()
117 hri->osize = HID_RSIZE_MAX; in hidbus_fill_rdesc_info()
120 if (hri->fsize > HID_RSIZE_MAX) { in hidbus_fill_rdesc_info()
122 hri->fsize); in hidbus_fill_rdesc_info()
123 hri->fsize = HID_RSIZE_MAX; in hidbus_fill_rdesc_info()
133 uint32_t *flags, uint8_t *id, struct hid_absinfo *ai) in hidbus_locate() argument
143 if (index--) in hidbus_locate()
149 if (id != NULL) in hidbus_locate()
150 *id = h.report_ID; in hidbus_locate()
163 loc->size = 0; in hidbus_locate()
166 if (id != NULL) in hidbus_locate()
167 *id = 0; in hidbus_locate()
203 tlc->mtx = &sc->mtx; in hidbus_add_child()
205 sx_xlock(&sc->sx); in hidbus_add_child()
206 CK_STAILQ_INSERT_TAIL(&sc->tlcs, tlc, link); in hidbus_add_child()
207 sx_unlock(&sc->sx); in hidbus_add_child()
246 sc->nauto = index; in hidbus_enumerate_children()
258 &sc->rdesc); in hidbus_attach_children()
260 error = hidbus_enumerate_children(dev, sc->rdesc.data, sc->rdesc.len); in hidbus_attach_children()
265 * hidbus_attach_children() can recurse through device_identify-> in hidbus_attach_children()
269 sc->nest++; in hidbus_attach_children()
271 sc->nest--; in hidbus_attach_children()
272 if (sc->nest != 0) in hidbus_attach_children()
275 if (hid_is_keyboard(sc->rdesc.data, sc->rdesc.len) != 0) in hidbus_attach_children()
286 device_t *children, bus; in hidbus_detach_children() local
293 bus = is_bus ? dev : device_get_parent(dev); in hidbus_detach_children()
295 KASSERT(device_get_devclass(bus) == devclass_find("hidbus"), in hidbus_detach_children()
300 error = bus_generic_detach(bus); in hidbus_detach_children()
306 error = device_get_children(bus, &children, &i); in hidbus_detach_children()
309 while (i-- > 0) { in hidbus_detach_children()
315 error = device_delete_child(bus, children[i]); in hidbus_detach_children()
325 HID_INTR_UNSETUP(device_get_parent(bus), bus); in hidbus_detach_children()
334 device_set_desc(dev, "HID bus"); in hidbus_probe()
349 sc->dev = dev; in hidbus_attach()
350 CK_STAILQ_INIT(&sc->tlcs); in hidbus_attach()
351 mtx_init(&sc->mtx, "hidbus ivar lock", NULL, MTX_DEF); in hidbus_attach()
352 sx_init(&sc->sx, "hidbus ivar list lock"); in hidbus_attach()
355 * Ignore error. It is possible for non-HID device e.g. XBox360 gamepad in hidbus_attach()
358 d_len = devinfo->rdescsize; in hidbus_attach()
369 hidbus_fill_rdesc_info(&sc->rdesc, d_ptr, d_len); in hidbus_attach()
371 sc->nowrite = hid_test_quirk(devinfo, HQ_NOWRITE); in hidbus_attach()
388 sx_destroy(&sc->sx); in hidbus_detach()
389 mtx_destroy(&sc->mtx); in hidbus_detach()
390 free(sc->rdesc.data, M_DEVBUF); in hidbus_detach()
396 hidbus_child_detached(device_t bus, device_t child) in hidbus_child_detached() argument
398 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_child_detached()
401 KASSERT(tlc->refcnt == 0, ("Child device is running")); in hidbus_child_detached()
402 tlc->mtx = &sc->mtx; in hidbus_child_detached()
403 tlc->intr_handler = NULL; in hidbus_child_detached()
404 tlc->flags &= ~HIDBUS_FLAG_CAN_POLL; in hidbus_child_detached()
420 hidbus_child_deleted(device_t bus, device_t child) in hidbus_child_deleted() argument
422 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_child_deleted()
425 sx_xlock(&sc->sx); in hidbus_child_deleted()
426 KASSERT(tlc->refcnt == 0, ("Child device is running")); in hidbus_child_deleted()
427 CK_STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link); in hidbus_child_deleted()
428 sx_unlock(&sc->sx); in hidbus_child_deleted()
429 epoch_call(INPUT_EPOCH, hidbus_ivar_dtor, &tlc->epoch_ctx); in hidbus_child_deleted()
433 hidbus_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) in hidbus_read_ivar() argument
435 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_read_ivar()
440 *result = tlc->index; in hidbus_read_ivar()
443 *result = tlc->usage; in hidbus_read_ivar()
446 *result = tlc->flags; in hidbus_read_ivar()
449 *result = tlc->driver_info; in hidbus_read_ivar()
452 *result = (uintptr_t)(tlc->mtx == &sc->mtx ? NULL : tlc->mtx); in hidbus_read_ivar()
461 hidbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value) in hidbus_write_ivar() argument
463 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_write_ivar()
468 tlc->index = value; in hidbus_write_ivar()
471 tlc->usage = value; in hidbus_write_ivar()
474 tlc->flags = value; in hidbus_write_ivar()
477 device_get_parent(bus), bus, NULL, NULL, NULL); in hidbus_write_ivar()
480 tlc->driver_info = value; in hidbus_write_ivar()
483 tlc->mtx = (struct mtx *)value == NULL ? in hidbus_write_ivar()
484 &sc->mtx : (struct mtx *)value; in hidbus_write_ivar()
494 hidbus_child_location(device_t bus, device_t child, struct sbuf *sb) in hidbus_child_location() argument
498 sbuf_printf(sb, "index=%hhu", tlc->index); in hidbus_child_location()
504 hidbus_child_pnpinfo(device_t bus, device_t child, struct sbuf *sb) in hidbus_child_pnpinfo() argument
507 struct hid_device_info *devinfo = device_get_ivars(bus); in hidbus_child_pnpinfo()
509 sbuf_printf(sb, "page=0x%04x usage=0x%04x bus=0x%02hx " in hidbus_child_pnpinfo()
511 HID_GET_USAGE_PAGE(tlc->usage), HID_GET_USAGE(tlc->usage), in hidbus_child_pnpinfo()
512 devinfo->idBus, devinfo->idVendor, devinfo->idProduct, in hidbus_child_pnpinfo()
513 devinfo->idVersion, devinfo->idPnP[0] == '\0' ? "" : " _HID=", in hidbus_child_pnpinfo()
514 devinfo->idPnP[0] == '\0' ? "" : devinfo->idPnP); in hidbus_child_pnpinfo()
521 device_t bus = device_get_parent(child); in hidbus_set_desc() local
522 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_set_desc()
523 struct hid_device_info *devinfo = device_get_ivars(bus); in hidbus_set_desc()
527 if (suffix != NULL && strcasestr(devinfo->name, suffix) == NULL && in hidbus_set_desc()
528 (sc->nauto > 1 || (tlc->flags & HIDBUS_FLAG_AUTOCHILD) == 0)) in hidbus_set_desc()
529 device_set_descf(child, "%s %s", devinfo->name, suffix); in hidbus_set_desc()
531 device_set_desc(child, devinfo->name); in hidbus_set_desc()
535 hidbus_find_child(device_t bus, int32_t usage) in hidbus_find_child() argument
543 if (device_get_children(bus, &children, &ccount) != 0) in hidbus_find_child()
567 * TODO: Add check for input report ID. in hidbus_intr()
574 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) { in hidbus_intr()
575 if (tlc->refcnt == 0 || tlc->intr_handler == NULL) in hidbus_intr()
578 if ((tlc->flags & HIDBUS_FLAG_CAN_POLL) != 0) in hidbus_intr()
579 tlc->intr_handler(tlc->intr_ctx, buf, len); in hidbus_intr()
581 mtx_lock(tlc->mtx); in hidbus_intr()
582 tlc->intr_handler(tlc->intr_ctx, buf, len); in hidbus_intr()
583 mtx_unlock(tlc->mtx); in hidbus_intr()
595 tlc->intr_handler = handler; in hidbus_set_intr()
596 tlc->intr_ctx = context; in hidbus_set_intr()
600 hidbus_intr_start(device_t bus, device_t child) in hidbus_intr_start() argument
602 MPASS(bus == device_get_parent(child)); in hidbus_intr_start()
603 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_intr_start()
609 if (sx_xlock_sig(&sc->sx) != 0) in hidbus_intr_start()
611 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) { in hidbus_intr_start()
612 refcnted |= (tlc->refcnt != 0); in hidbus_intr_start()
614 mtx_lock(tlc->mtx); in hidbus_intr_start()
615 ++tlc->refcnt; in hidbus_intr_start()
616 mtx_unlock(tlc->mtx); in hidbus_intr_start()
619 error = refcnted ? 0 : hid_intr_start(bus); in hidbus_intr_start()
620 sx_unlock(&sc->sx); in hidbus_intr_start()
626 hidbus_intr_stop(device_t bus, device_t child) in hidbus_intr_stop() argument
628 MPASS(bus == device_get_parent(child)); in hidbus_intr_stop()
629 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_intr_stop()
635 if (sx_xlock_sig(&sc->sx) != 0) in hidbus_intr_stop()
637 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) { in hidbus_intr_stop()
639 mtx_lock(tlc->mtx); in hidbus_intr_stop()
640 MPASS(tlc->refcnt != 0); in hidbus_intr_stop()
641 --tlc->refcnt; in hidbus_intr_stop()
642 mtx_unlock(tlc->mtx); in hidbus_intr_stop()
644 refcnted |= (tlc->refcnt != 0); in hidbus_intr_stop()
646 error = refcnted ? 0 : hid_intr_stop(bus); in hidbus_intr_stop()
647 sx_unlock(&sc->sx); in hidbus_intr_stop()
653 hidbus_intr_poll(device_t bus, device_t child __unused) in hidbus_intr_poll() argument
655 hid_intr_poll(bus); in hidbus_intr_poll()
661 device_t bus = device_get_parent(child); in hidbus_get_rdesc_info() local
662 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_get_rdesc_info()
664 return (&sc->rdesc); in hidbus_get_rdesc_info()
677 device_t bus; in hid_get_report_descr() local
680 bus = device_get_devclass(dev) == devclass_find("hidbus") ? in hid_get_report_descr()
682 sc = device_get_softc(bus); in hid_get_report_descr()
688 if (sc->rdesc.data == NULL || sc->rdesc.len == 0) in hid_get_report_descr()
692 *data = sc->rdesc.data; in hid_get_report_descr()
694 *len = sc->rdesc.len; in hid_get_report_descr()
713 device_t bus; in hid_set_report_descr() local
721 bus = is_bus ? dev : device_get_parent(dev); in hid_set_report_descr()
722 sc = device_get_softc(bus); in hid_set_report_descr()
728 if (is_bus && sc->overloaded) in hid_set_report_descr()
745 sc->overloaded = true; in hid_set_report_descr()
746 free(sc->rdesc.data, M_DEVBUF); in hid_set_report_descr()
747 bcopy(&rdesc, &sc->rdesc, sizeof(struct hid_rdesc_info)); in hid_set_report_descr()
749 error = hidbus_attach_children(bus); in hid_set_report_descr()
773 uint8_t id; in hidbus_write() local
780 if (sc->nowrite) { in hidbus_write()
781 /* try to extract the ID byte */ in hidbus_write()
782 id = (sc->rdesc.oid & (len > 0)) ? *(const uint8_t*)data : 0; in hidbus_write()
783 return (hid_set_report(dev, data, len, HID_OUTPUT_REPORT, id)); in hidbus_write()
791 hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id) in hidbus_get_report() argument
793 return (hid_get_report(dev, data, maxlen, actlen, type, id)); in hidbus_get_report()
798 hid_size_t len, uint8_t type, uint8_t id) in hidbus_set_report() argument
800 return (hid_set_report(dev, data, len, type, id)); in hidbus_set_report()
805 uint8_t id) in hidbus_set_idle() argument
807 return (hid_set_idle(dev, duration, id)); in hidbus_set_idle()
823 /*------------------------------------------------------------------------*
832 *------------------------------------------------------------------------*/
834 hidbus_lookup_id(device_t dev, const struct hid_device_id *id, int nitems_id) in hidbus_lookup_id() argument
841 if (id == NULL) { in hidbus_lookup_id()
845 id_end = id + nitems_id; in hidbus_lookup_id()
855 for (; id != id_end; id++) { in hidbus_lookup_id()
857 if (is_child && (id->match_flag_page) && in hidbus_lookup_id()
858 (id->page != HID_GET_USAGE_PAGE(usage))) { in hidbus_lookup_id()
861 if (is_child && (id->match_flag_usage) && in hidbus_lookup_id()
862 (id->usage != HID_GET_USAGE(usage))) { in hidbus_lookup_id()
865 if ((id->match_flag_bus) && in hidbus_lookup_id()
866 (id->idBus != info->idBus)) { in hidbus_lookup_id()
869 if ((id->match_flag_vendor) && in hidbus_lookup_id()
870 (id->idVendor != info->idVendor)) { in hidbus_lookup_id()
873 if ((id->match_flag_product) && in hidbus_lookup_id()
874 (id->idProduct != info->idProduct)) { in hidbus_lookup_id()
877 if ((id->match_flag_ver_lo) && in hidbus_lookup_id()
878 (id->idVersion_lo > info->idVersion)) { in hidbus_lookup_id()
881 if ((id->match_flag_ver_hi) && in hidbus_lookup_id()
882 (id->idVersion_hi < info->idVersion)) { in hidbus_lookup_id()
885 if (id->match_flag_pnp && in hidbus_lookup_id()
886 strncmp(id->idPnP, info->idPnP, HID_PNP_ID_SIZE) != 0) { in hidbus_lookup_id()
890 return (id); in hidbus_lookup_id()
897 /*------------------------------------------------------------------------*
898 * hidbus_lookup_driver_info - factored out code
903 *------------------------------------------------------------------------*/
905 hidbus_lookup_driver_info(device_t child, const struct hid_device_id *id, in hidbus_lookup_driver_info() argument
909 id = hidbus_lookup_id(child, id, nitems_id); in hidbus_lookup_driver_info()
910 if (id) { in hidbus_lookup_driver_info()
912 hidbus_set_driver_info(child, id->driver_info); in hidbus_lookup_driver_info()
921 device_t bus; in hid_get_device_info() local
923 bus = device_get_devclass(dev) == devclass_find("hidbus") ? in hid_get_device_info()
926 return (device_get_ivars(bus)); in hid_get_device_info()
937 /* bus interface */