summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoranton <anton@cvs.openbsd.org>2021-02-04 16:18:35 +0000
committeranton <anton@cvs.openbsd.org>2021-02-04 16:18:35 +0000
commit1c09afcab2bcab8ec16fadd858351f7a4b7f6e05 (patch)
tree4fbd4d64dee664f6d1627bf36fc2a98a817feae5 /sys/dev
parenta5eb5c53965d5797670735b827cea755dd9ebac3 (diff)
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
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uhidev.c27
-rw-r--r--sys/dev/usb/uhidev.h3
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);