Lines Matching +full:data +full:- +full:bus

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 #include <sys/bus.h>
89 hidbus_fill_rdesc_info(struct hid_rdesc_info *hri, const void *data, in hidbus_fill_rdesc_info() argument
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()
143 if (index--) in hidbus_locate()
163 loc->size = 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()
213 hidbus_enumerate_children(device_t dev, const void* data, hid_size_t len) in hidbus_enumerate_children() argument
221 if (data == NULL || len == 0) in hidbus_enumerate_children()
225 hd = hid_start_parse(data, len, 1 << hid_input); in hidbus_enumerate_children()
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->active, ("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->active, ("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()
574 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) { in hidbus_intr()
575 if (!tlc->active || 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()
607 if (sx_xlock_sig(&sc->sx) != 0) in hidbus_intr_start()
609 mtx_lock(ivar->mtx); in hidbus_intr_start()
610 ivar->active = true; in hidbus_intr_start()
611 mtx_unlock(ivar->mtx); in hidbus_intr_start()
612 error = hid_intr_start(bus); in hidbus_intr_start()
613 sx_unlock(&sc->sx); in hidbus_intr_start()
619 hidbus_intr_stop(device_t bus, device_t child) in hidbus_intr_stop() argument
621 MPASS(bus == device_get_parent(child)); in hidbus_intr_stop()
622 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_intr_stop()
628 if (sx_xlock_sig(&sc->sx) != 0) in hidbus_intr_stop()
630 mtx_lock(ivar->mtx); in hidbus_intr_stop()
631 ivar->active = false; in hidbus_intr_stop()
632 mtx_unlock(ivar->mtx); in hidbus_intr_stop()
633 CK_STAILQ_FOREACH(tlc, &sc->tlcs, link) in hidbus_intr_stop()
634 active |= tlc->active; in hidbus_intr_stop()
635 error = active ? 0 : hid_intr_stop(bus); in hidbus_intr_stop()
636 sx_unlock(&sc->sx); in hidbus_intr_stop()
642 hidbus_intr_poll(device_t bus, device_t child __unused) in hidbus_intr_poll() argument
644 hid_intr_poll(bus); in hidbus_intr_poll()
650 device_t bus = device_get_parent(child); in hidbus_get_rdesc_info() local
651 struct hidbus_softc *sc = device_get_softc(bus); in hidbus_get_rdesc_info()
653 return (&sc->rdesc); in hidbus_get_rdesc_info()
664 hid_get_report_descr(device_t dev, void **data, hid_size_t *len) in hid_get_report_descr() argument
666 device_t bus; in hid_get_report_descr() local
669 bus = device_get_devclass(dev) == devclass_find("hidbus") ? in hid_get_report_descr()
671 sc = device_get_softc(bus); in hid_get_report_descr()
677 if (sc->rdesc.data == NULL || sc->rdesc.len == 0) in hid_get_report_descr()
680 if (data != NULL) in hid_get_report_descr()
681 *data = sc->rdesc.data; in hid_get_report_descr()
683 *len = sc->rdesc.len; in hid_get_report_descr()
699 hid_set_report_descr(device_t dev, const void *data, hid_size_t len) in hid_set_report_descr() argument
702 device_t bus; in hid_set_report_descr() local
710 bus = is_bus ? dev : device_get_parent(dev); in hid_set_report_descr()
711 sc = device_get_softc(bus); in hid_set_report_descr()
717 if (is_bus && sc->overloaded) in hid_set_report_descr()
721 DPRINTFN(5, "data = %*D\n", len, data, " "); in hid_set_report_descr()
723 error = hidbus_fill_rdesc_info(&rdesc, data, len); in hid_set_report_descr()
731 /* Make private copy to handle a case of dynamicaly allocated data. */ in hid_set_report_descr()
732 rdesc.data = malloc(len, M_DEVBUF, M_ZERO | M_WAITOK); in hid_set_report_descr()
733 bcopy(data, rdesc.data, len); in hid_set_report_descr()
734 sc->overloaded = true; in hid_set_report_descr()
735 free(sc->rdesc.data, M_DEVBUF); in hid_set_report_descr()
736 bcopy(&rdesc, &sc->rdesc, sizeof(struct hid_rdesc_info)); in hid_set_report_descr()
738 error = hidbus_attach_children(bus); in hid_set_report_descr()
744 hidbus_get_rdesc(device_t dev, device_t child __unused, void *data, in hidbus_get_rdesc() argument
747 return (hid_get_rdesc(dev, data, len)); in hidbus_get_rdesc()
751 hidbus_read(device_t dev, device_t child __unused, void *data, in hidbus_read() argument
754 return (hid_read(dev, data, maxlen, actlen)); in hidbus_read()
758 hidbus_write(device_t dev, device_t child __unused, const void *data, in hidbus_write() argument
769 if (sc->nowrite) { in hidbus_write()
771 id = (sc->rdesc.oid & (len > 0)) ? *(const uint8_t*)data : 0; in hidbus_write()
772 return (hid_set_report(dev, data, len, HID_OUTPUT_REPORT, id)); in hidbus_write()
775 return (hid_write(dev, data, len)); in hidbus_write()
779 hidbus_get_report(device_t dev, device_t child __unused, void *data, in hidbus_get_report() argument
782 return (hid_get_report(dev, data, maxlen, actlen, type, id)); in hidbus_get_report()
786 hidbus_set_report(device_t dev, device_t child __unused, const void *data, in hidbus_set_report() argument
789 return (hid_set_report(dev, data, len, type, id)); in hidbus_set_report()
807 uintptr_t data) in hidbus_ioctl() argument
809 return (hid_ioctl(dev, cmd, data)); in hidbus_ioctl()
812 /*------------------------------------------------------------------------*
821 *------------------------------------------------------------------------*/
846 if (is_child && (id->match_flag_page) && in hidbus_lookup_id()
847 (id->page != HID_GET_USAGE_PAGE(usage))) { in hidbus_lookup_id()
850 if (is_child && (id->match_flag_usage) && in hidbus_lookup_id()
851 (id->usage != HID_GET_USAGE(usage))) { in hidbus_lookup_id()
854 if ((id->match_flag_bus) && in hidbus_lookup_id()
855 (id->idBus != info->idBus)) { in hidbus_lookup_id()
858 if ((id->match_flag_vendor) && in hidbus_lookup_id()
859 (id->idVendor != info->idVendor)) { in hidbus_lookup_id()
862 if ((id->match_flag_product) && in hidbus_lookup_id()
863 (id->idProduct != info->idProduct)) { in hidbus_lookup_id()
866 if ((id->match_flag_ver_lo) && in hidbus_lookup_id()
867 (id->idVersion_lo > info->idVersion)) { in hidbus_lookup_id()
870 if ((id->match_flag_ver_hi) && in hidbus_lookup_id()
871 (id->idVersion_hi < info->idVersion)) { in hidbus_lookup_id()
874 if (id->match_flag_pnp && in hidbus_lookup_id()
875 strncmp(id->idPnP, info->idPnP, HID_PNP_ID_SIZE) != 0) { in hidbus_lookup_id()
886 /*------------------------------------------------------------------------*
887 * hidbus_lookup_driver_info - factored out code
892 *------------------------------------------------------------------------*/
901 hidbus_set_driver_info(child, id->driver_info); in hidbus_lookup_driver_info()
910 device_t bus; in hid_get_device_info() local
912 bus = device_get_devclass(dev) == devclass_find("hidbus") ? in hid_get_device_info()
915 return (device_get_ivars(bus)); in hid_get_device_info()
926 /* bus interface */