summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorJoshua Stein <jcs@cvs.openbsd.org>2021-03-08 14:35:58 +0000
committerJoshua Stein <jcs@cvs.openbsd.org>2021-03-08 14:35:58 +0000
commit5247762fbcff94e3523868fa05f18c9ef6e7de2f (patch)
tree575401f7060f36bda26f36095d8deab1f0471cbc /sys/dev/usb
parent6146cd5d9580443e3bc02939ea4924be4f00ded7 (diff)
Allow uhidev child devices to claim selective report ids
There may be multiple matching devices on a single uhidev device but the first device that responds to UHIDEV_CLAIM_ALLREPORTID will block the others from attaching. Change this to UHIDEV_CLAIM_MULTIPLE_REPORTID and require any devices wanting some/all report ids to fill in the claimed array in uhidev_attach_arg with just the reports it needs. uhidev can then run match routines for other drivers with the available report ids. ok anton
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/fido.c4
-rw-r--r--sys/dev/usb/ucycom.c4
-rw-r--r--sys/dev/usb/ugold.c4
-rw-r--r--sys/dev/usb/uhid.c4
-rw-r--r--sys/dev/usb/uhidev.c19
-rw-r--r--sys/dev/usb/uhidev.h6
-rw-r--r--sys/dev/usb/ujoy.c4
-rw-r--r--sys/dev/usb/umt.c54
-rw-r--r--sys/dev/usb/uoaklux.c4
-rw-r--r--sys/dev/usb/uoakrh.c4
-rw-r--r--sys/dev/usb/uoakv.c4
-rw-r--r--sys/dev/usb/upd.c4
-rw-r--r--sys/dev/usb/uslhcom.c4
-rw-r--r--sys/dev/usb/uthum.c4
-rw-r--r--sys/dev/usb/utrh.c4
-rw-r--r--sys/dev/usb/utwitch.c4
16 files changed, 74 insertions, 57 deletions
diff --git a/sys/dev/usb/fido.c b/sys/dev/usb/fido.c
index 77bd9b12175..c6d846aaa84 100644
--- a/sys/dev/usb/fido.c
+++ b/sys/dev/usb/fido.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fido.c,v 1.2 2019/12/18 05:09:53 deraadt Exp $ */
+/* $OpenBSD: fido.c,v 1.3 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2019 Reyk Floeter <reyk@openbsd.org>
@@ -63,7 +63,7 @@ fido_match(struct device *parent, void *match, void *aux)
void *desc;
int ret = UMATCH_NONE;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (ret);
/* Find the FIDO usage page and U2F collection */
diff --git a/sys/dev/usb/ucycom.c b/sys/dev/usb/ucycom.c
index ca6d6e9c6b2..ca8636f0a7f 100644
--- a/sys/dev/usb/ucycom.c
+++ b/sys/dev/usb/ucycom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ucycom.c,v 1.38 2020/02/25 10:03:39 mpi Exp $ */
+/* $OpenBSD: ucycom.c,v 1.39 2021/03/08 14:35:57 jcs Exp $ */
/* $NetBSD: ucycom.c,v 1.3 2005/08/05 07:27:47 skrll Exp $ */
/*
@@ -165,7 +165,7 @@ ucycom_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
return (usb_lookup(ucycom_devs, uha->uaa->vendor, uha->uaa->product) != NULL ?
diff --git a/sys/dev/usb/ugold.c b/sys/dev/usb/ugold.c
index bc2d84ca42e..c939966760e 100644
--- a/sys/dev/usb/ugold.c
+++ b/sys/dev/usb/ugold.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ugold.c,v 1.15 2020/08/17 04:26:57 gnezdo Exp $ */
+/* $OpenBSD: ugold.c,v 1.16 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2013 Takayoshi SASANO <uaa@openbsd.org>
@@ -110,7 +110,7 @@ ugold_match(struct device *parent, void *match, void *aux)
int size;
void *desc;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
if (usb_lookup(ugold_devs, uha->uaa->vendor, uha->uaa->product) == NULL)
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index ba21e8cf96f..085c1523ccf 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhid.c,v 1.83 2021/01/29 16:59:41 sthen Exp $ */
+/* $OpenBSD: uhid.c,v 1.84 2021/03/08 14:35:57 jcs Exp $ */
/* $NetBSD: uhid.c,v 1.57 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -115,7 +115,7 @@ uhid_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
return (UMATCH_IFACECLASS_GENERIC);
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 24b7841d837..d777cfb6e45 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.c,v 1.89 2021/02/15 11:26:00 mglocker Exp $ */
+/* $OpenBSD: uhidev.c,v 1.90 2021/03/08 14:35:57 jcs Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -250,21 +250,28 @@ uhidev_attach(struct device *parent, struct device *self, void *aux)
uha.uaa = uaa;
uha.parent = sc;
- uha.reportid = UHIDEV_CLAIM_ALLREPORTID;
+ uha.reportid = UHIDEV_CLAIM_MULTIPLE_REPORTID;
+ uha.nreports = nrepid;
+ uha.claimed = malloc(nrepid, M_TEMP, M_WAITOK|M_ZERO);
- /* Look for a driver claiming all report IDs first. */
+ /* Look for a driver claiming multiple report IDs first. */
dev = config_found_sm(self, &uha, NULL, uhidevsubmatch);
if (dev != NULL) {
for (repid = 0; repid < nrepid; repid++) {
/*
* Could already be assigned by uhidev_set_report_dev().
*/
- if (sc->sc_subdevs[repid] == NULL)
+ if (sc->sc_subdevs[repid] != NULL)
+ continue;
+
+ if (uha.claimed[repid])
sc->sc_subdevs[repid] = (struct uhidev *)dev;
}
- return;
}
+ free(uha.claimed, M_TEMP, nrepid);
+ uha.claimed = NULL;
+
for (repid = 0; repid < nrepid; repid++) {
DPRINTF(("%s: try repid=%d\n", __func__, repid));
if (hid_report_size(desc, size, hid_input, repid) == 0 &&
@@ -355,7 +362,7 @@ uhidevprint(void *aux, const char *pnp)
if (pnp)
printf("uhid at %s", pnp);
- if (uha->reportid != 0 && uha->reportid != UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid != 0 && uha->reportid != UHIDEV_CLAIM_MULTIPLE_REPORTID)
printf(" reportid %d", uha->reportid);
return (UNCONF);
}
diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h
index 7cce36f515d..cb83045084c 100644
--- a/sys/dev/usb/uhidev.h
+++ b/sys/dev/usb/uhidev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.h,v 1.27 2021/02/11 06:55:10 anton Exp $ */
+/* $OpenBSD: uhidev.h,v 1.28 2021/03/08 14:35:57 jcs Exp $ */
/* $NetBSD: uhidev.h,v 1.3 2002/10/08 09:56:17 dan Exp $ */
/*
@@ -81,7 +81,9 @@ struct uhidev_attach_arg {
struct usb_attach_arg *uaa;
struct uhidev_softc *parent;
uint8_t reportid;
-#define UHIDEV_CLAIM_ALLREPORTID 255
+#define UHIDEV_CLAIM_MULTIPLE_REPORTID 255
+ uint8_t nreports;
+ uint8_t *claimed;
};
int uhidev_report_type_conv(int);
diff --git a/sys/dev/usb/ujoy.c b/sys/dev/usb/ujoy.c
index 18a35d737b9..ca461e5969a 100644
--- a/sys/dev/usb/ujoy.c
+++ b/sys/dev/usb/ujoy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ujoy.c,v 1.1 2021/01/23 05:08:36 thfr Exp $ */
+/* $OpenBSD: ujoy.c,v 1.2 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2021 Thomas Frohwein <thfr@openbsd.org>
@@ -104,7 +104,7 @@ ujoy_match(struct device *parent, void *match, void *aux)
void *desc;
int ret = UMATCH_NONE;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (ret);
/* Find the general usage page and gamecontroller collections */
diff --git a/sys/dev/usb/umt.c b/sys/dev/usb/umt.c
index 863781f2659..a3fd5ce9c28 100644
--- a/sys/dev/usb/umt.c
+++ b/sys/dev/usb/umt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: umt.c,v 1.2 2020/08/23 11:08:02 mglocker Exp $ */
+/* $OpenBSD: umt.c,v 1.3 2021/03/08 14:35:57 jcs Exp $ */
/*
* USB multitouch touchpad driver for devices conforming to
* Windows Precision Touchpad standard
@@ -61,8 +61,8 @@ const struct wsmouse_accessops umt_accessops = {
};
int umt_match(struct device *, void *, void *);
-int umt_find_winptp_reports(struct uhidev_softc *, void *, int,
- struct umt_softc *);
+int umt_find_winptp_reports(struct uhidev_softc *, void *, int, int *,
+ int *, int *);
void umt_attach(struct device *, struct device *, void *);
int umt_hidev_get_report(struct device *, int, int, void *, int);
int umt_hidev_set_report(struct device *, int, int, void *, int);
@@ -83,13 +83,19 @@ int
umt_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
+ int input = 0, conf = 0, cap = 0;
int size;
void *desc;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID) {
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID) {
uhidev_get_report_desc(uha->parent, &desc, &size);
- if (umt_find_winptp_reports(uha->parent, desc, size, NULL))
+ if (umt_find_winptp_reports(uha->parent, desc, size, &input,
+ &conf, &cap)) {
+ uha->claimed[input] = 1;
+ uha->claimed[conf] = 1;
+ uha->claimed[cap] = 1;
return (UMATCH_DEVCLASS_DEVSUBCLASS);
+ }
}
return (UMATCH_NONE);
@@ -97,16 +103,17 @@ umt_match(struct device *parent, void *match, void *aux)
int
umt_find_winptp_reports(struct uhidev_softc *parent, void *desc, int size,
- struct umt_softc *sc)
+ int *input, int *config, int *cap)
{
int repid;
- int input = 0, conf = 0, cap = 0;
+ int finput = 0, fconf = 0, fcap = 0;
- if (sc != NULL) {
- sc->sc_rep_input = -1;
- sc->sc_rep_config = -1;
- sc->sc_rep_cap = -1;
- }
+ if (input != NULL)
+ *input = -1;
+ if (config != NULL)
+ *config = -1;
+ if (cap != NULL)
+ *cap = -1;
for (repid = 0; repid < parent->sc_nrepid; repid++) {
if (hid_report_size(desc, size, hid_input, repid) == 0 &&
@@ -116,26 +123,26 @@ umt_find_winptp_reports(struct uhidev_softc *parent, void *desc, int size,
if (hid_is_collection(desc, size, repid,
HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHPAD))) {
- input = 1;
- if (sc != NULL && sc->sc_rep_input == -1)
- sc->sc_rep_input = repid;
+ finput = 1;
+ if (input != NULL && *input == -1)
+ *input = repid;
} else if (hid_is_collection(desc, size, repid,
HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIG))) {
- conf = 1;
- if (sc != NULL && sc->sc_rep_config == -1)
- sc->sc_rep_config = repid;
+ fconf = 1;
+ if (config != NULL && *config == -1)
+ *config = repid;
}
/* capabilities report could be anywhere */
if (hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS,
HUD_CONTACT_MAX), repid, hid_feature, NULL, NULL)) {
- cap = 1;
- if (sc != NULL && sc->sc_rep_cap == -1)
- sc->sc_rep_cap = repid;
+ fcap = 1;
+ if (cap != NULL && *cap == -1)
+ *cap = repid;
}
}
- return (conf && input && cap);
+ return (fconf && finput && fcap);
}
void
@@ -153,7 +160,8 @@ umt_attach(struct device *parent, struct device *self, void *aux)
usbd_set_idle(uha->parent->sc_udev, uha->parent->sc_ifaceno, 0, 0);
uhidev_get_report_desc(uha->parent, &desc, &size);
- umt_find_winptp_reports(uha->parent, desc, size, sc);
+ umt_find_winptp_reports(uha->parent, desc, size, &sc->sc_rep_input,
+ &sc->sc_rep_config, &sc->sc_rep_cap);
memset(mt, 0, sizeof(sc->sc_mt));
diff --git a/sys/dev/usb/uoaklux.c b/sys/dev/usb/uoaklux.c
index 3932b139a51..c97bdf57285 100644
--- a/sys/dev/usb/uoaklux.c
+++ b/sys/dev/usb/uoaklux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uoaklux.c,v 1.13 2017/04/08 02:57:25 deraadt Exp $ */
+/* $OpenBSD: uoaklux.c,v 1.14 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2012 Yojiro UO <yuo@nui.org>
@@ -107,7 +107,7 @@ uoaklux_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
if (uoaklux_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
diff --git a/sys/dev/usb/uoakrh.c b/sys/dev/usb/uoakrh.c
index 66a030409de..1e1e49a426c 100644
--- a/sys/dev/usb/uoakrh.c
+++ b/sys/dev/usb/uoakrh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uoakrh.c,v 1.15 2017/04/08 02:57:25 deraadt Exp $ */
+/* $OpenBSD: uoakrh.c,v 1.16 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2012 Yojiro UO <yuo@nui.org>
@@ -110,7 +110,7 @@ uoakrh_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
if (uoakrh_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
diff --git a/sys/dev/usb/uoakv.c b/sys/dev/usb/uoakv.c
index a8cdb734001..2963e47da0d 100644
--- a/sys/dev/usb/uoakv.c
+++ b/sys/dev/usb/uoakv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uoakv.c,v 1.13 2017/04/08 02:57:25 deraadt Exp $ */
+/* $OpenBSD: uoakv.c,v 1.14 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2012 Yojiro UO <yuo@nui.org>
@@ -110,7 +110,7 @@ uoakv_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
if (uoakv_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
diff --git a/sys/dev/usb/upd.c b/sys/dev/usb/upd.c
index 50cc25af08f..ad65b77718b 100644
--- a/sys/dev/usb/upd.c
+++ b/sys/dev/usb/upd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: upd.c,v 1.28 2021/01/29 16:59:41 sthen Exp $ */
+/* $OpenBSD: upd.c,v 1.29 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2015 David Higgs <higgsd@gmail.com>
@@ -155,7 +155,7 @@ upd_match(struct device *parent, void *match, void *aux)
int ret = UMATCH_NONE;
int i;
- if (uha->reportid != UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid != UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (ret);
DPRINTF(("upd: vendor=0x%04x, product=0x%04x\n", uha->uaa->vendor,
diff --git a/sys/dev/usb/uslhcom.c b/sys/dev/usb/uslhcom.c
index 39db391aecd..15291aae645 100644
--- a/sys/dev/usb/uslhcom.c
+++ b/sys/dev/usb/uslhcom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uslhcom.c,v 1.6 2017/04/08 02:57:25 deraadt Exp $ */
+/* $OpenBSD: uslhcom.c,v 1.7 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2015 SASANO Takayoshi <uaa@openbsd.org>
@@ -115,7 +115,7 @@ uslhcom_match(struct device *parent, void *match, void *aux)
struct uhidev_attach_arg *uha = aux;
/* use all report IDs */
- if (uha->reportid != UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid != UHIDEV_CLAIM_MULTIPLE_REPORTID)
return UMATCH_NONE;
return (usb_lookup(uslhcom_devs,
diff --git a/sys/dev/usb/uthum.c b/sys/dev/usb/uthum.c
index 601abdc64ab..d368472c19a 100644
--- a/sys/dev/usb/uthum.c
+++ b/sys/dev/usb/uthum.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthum.c,v 1.34 2020/02/14 14:55:30 mpi Exp $ */
+/* $OpenBSD: uthum.c,v 1.35 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2009, 2010 Yojiro UO <yuo@nui.org>
@@ -167,7 +167,7 @@ uthum_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
if (uthum_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
diff --git a/sys/dev/usb/utrh.c b/sys/dev/usb/utrh.c
index cd6f43c06d9..c74ca0746ca 100644
--- a/sys/dev/usb/utrh.c
+++ b/sys/dev/usb/utrh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utrh.c,v 1.23 2020/02/25 10:03:39 mpi Exp $ */
+/* $OpenBSD: utrh.c,v 1.24 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2009 Yojiro UO <yuo@nui.org>
@@ -93,7 +93,7 @@ utrh_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
return (usb_lookup(utrh_devs, uha->uaa->vendor, uha->uaa->product) != NULL ?
diff --git a/sys/dev/usb/utwitch.c b/sys/dev/usb/utwitch.c
index cc8396a21dd..a7a5479700f 100644
--- a/sys/dev/usb/utwitch.c
+++ b/sys/dev/usb/utwitch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utwitch.c,v 1.20 2020/02/25 10:03:39 mpi Exp $ */
+/* $OpenBSD: utwitch.c,v 1.21 2021/03/08 14:35:57 jcs Exp $ */
/*
* Copyright (c) 2010 Yojiro UO <yuo@nui.org>
@@ -107,7 +107,7 @@ utwitch_match(struct device *parent, void *match, void *aux)
{
struct uhidev_attach_arg *uha = aux;
- if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID)
return (UMATCH_NONE);
return (usb_lookup(utwitch_devs, uha->uaa->vendor, uha->uaa->product) != NULL ?