From e013a115c721688bca7b98b4ec3cdb63a4798344 Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 4 Feb 2021 16:18:34 +0000 Subject: [PATCH] Add uhidev_set_report_dev() allowing usb drivers to early on install a handler for a specific report id. Needed by an upcoming driver in order to communicate with the device already in the attach routine. ok mglocker@ as part of a larger diff --- sys/dev/usb/uhidev.c | 27 +++++++++++++++++++++++---- sys/dev/usb/uhidev.h | 3 ++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index 16f440714c1..9915b660d9d 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhidev.c,v 1.85 2021/01/29 16:59:41 sthen Exp $ */ +/* $OpenBSD: uhidev.c,v 1.86 2021/02/04 16:18:34 anton Exp $ */ /* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */ /* @@ -256,8 +256,13 @@ uhidev_attach(struct device *parent, struct device *self, void *aux) /* Look for a driver claiming all report IDs first. */ dev = config_found_sm(self, &uha, NULL, uhidevsubmatch); if (dev != NULL) { - for (repid = 0; repid < nrepid; repid++) - sc->sc_subdevs[repid] = (struct uhidev *)dev; + for (repid = 0; repid < nrepid; repid++) { + /* + * Could already be assigned by uhidev_set_report_dev(). + */ + if (sc->sc_subdevs[repid] == NULL) + sc->sc_subdevs[repid] = (struct uhidev *)dev; + } return; } @@ -270,7 +275,9 @@ uhidev_attach(struct device *parent, struct device *self, void *aux) uha.reportid = repid; dev = config_found_sm(self, &uha, uhidevprint, uhidevsubmatch); - sc->sc_subdevs[repid] = (struct uhidev *)dev; + /* Could already be assigned by uhidev_set_report_dev(). */ + if (sc->sc_subdevs[repid] == NULL) + sc->sc_subdevs[repid] = (struct uhidev *)dev; } } @@ -992,3 +999,15 @@ uhidev_clear_iface_eps(struct uhidev_softc *sc, struct usbd_interface *iface) bad: printf("%s: clear endpoints failed!\n", __func__); } + +int +uhidev_set_report_dev(struct uhidev_softc *sc, struct uhidev *dev, int repid) +{ + if ((dev->sc_state & UHIDEV_OPEN) == 0) + return ENODEV; + if (repid >= sc->sc_nrepid) + return EINVAL; + + sc->sc_subdevs[repid] = dev; + return 0; +} diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h index 16657f1e712..5caba3d8304 100644 --- a/sys/dev/usb/uhidev.h +++ b/sys/dev/usb/uhidev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uhidev.h,v 1.25 2018/08/25 18:32:05 jcs Exp $ */ +/* $OpenBSD: uhidev.h,v 1.26 2021/02/04 16:18:34 anton Exp $ */ /* $NetBSD: uhidev.h,v 1.3 2002/10/08 09:56:17 dan Exp $ */ /* @@ -95,3 +95,4 @@ int uhidev_get_report(struct uhidev_softc *, int, int, void *, int); int uhidev_get_report_async(struct uhidev_softc *, int, int, void *, int, void *, void (*)(void *, int, void *, int)); usbd_status uhidev_write(struct uhidev_softc *, void *, int); +int uhidev_set_report_dev(struct uhidev_softc *, struct uhidev *, int); -- 2.20.1