upd(4) has been integrated to the tree a few hours ago.
it is disabled for now, so if you follow current and can test it, please
use this patch (mostly the same mpi@'s patch from yesterday, plus the
removal of the supported product/device-ids from usb_quirks.c).
if you have an ups with you which does not match any of the ones removed
from usb_quicks, please send me your usbdevs -v output.
thanks,
-a
Index: arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.363
diff -u -p -r1.363 GENERIC
--- arch/amd64/conf/GENERIC 17 Mar 2014 18:40:46 -0000 1.363
+++ arch/amd64/conf/GENERIC 17 Mar 2014 23:28:37 -0000
@@ -236,7 +236,7 @@ udsbr* at uhub? # D-Link DSB-R100 radio
radio* at udsbr? # USB radio
uberry* at uhub? # Research In Motion Blackberry
ugen* at uhub? # USB Generic driver
-#upd* at uhidev? # USB Power Devices sensors
+upd* at uhidev? # USB Power Devices sensors
uath* at uhub? # Atheros AR5005UG/AR5005UX
ural* at uhub? # Ralink RT2500USB
rum* at uhub? # Ralink RT2501USB/RT2601USB
Index: dev/usb/ucycom.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ucycom.c,v
retrieving revision 1.24
diff -u -p -r1.24 ucycom.c
--- dev/usb/ucycom.c 15 Nov 2013 08:25:31 -0000 1.24
+++ dev/usb/ucycom.c 17 Mar 2014 23:28:38 -0000
@@ -174,7 +174,9 @@ ucycom_match(struct device *parent, void
{
struct uhidev_attach_arg *uha = aux;
- DPRINTF(("ucycom match\n"));
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
+
return (usb_lookup(ucycom_devs, uha->uaa->vendor, uha->uaa->product) !=
NULL ?
UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
}
Index: dev/usb/ugold.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ugold.c,v
retrieving revision 1.3
diff -u -p -r1.3 ugold.c
--- dev/usb/ugold.c 4 Nov 2013 11:51:33 -0000 1.3
+++ dev/usb/ugold.c 17 Mar 2014 23:28:38 -0000
@@ -102,6 +102,9 @@ ugold_match(struct device *parent, void
int size;
void *desc;
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
+
if (usb_lookup(ugold_devs, uha->uaa->vendor, uha->uaa->product) == NULL)
return (UMATCH_NONE);
Index: dev/usb/uhid.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.55
diff -u -p -r1.55 uhid.c
--- dev/usb/uhid.c 19 Nov 2013 14:04:07 -0000 1.55
+++ dev/usb/uhid.c 17 Mar 2014 23:28:38 -0000
@@ -114,11 +114,10 @@ const struct cfattach uhid_ca = {
int
uhid_match(struct device *parent, void *match, void *aux)
{
-#ifdef UHID_DEBUG
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
-#endif
+ struct uhidev_attach_arg *uha = aux;
- DPRINTF(("uhid_match: report=%d\n", uha->reportid));
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
return (UMATCH_IFACECLASS_GENERIC);
}
Index: dev/usb/uhidev.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
retrieving revision 1.55
diff -u -p -r1.55 uhidev.c
--- dev/usb/uhidev.c 16 Mar 2014 10:54:40 -0000 1.55
+++ dev/usb/uhidev.c 17 Mar 2014 23:28:38 -0000
@@ -128,6 +128,7 @@ uhidev_attach(struct device *parent, str
int size, nrepid, repid, repsz;
int i, repsizes[256];
void *desc = NULL;
+ struct device *dev;
sc->sc_udev = uaa->device;
sc->sc_iface = uaa->iface;
@@ -217,19 +218,25 @@ uhidev_attach(struct device *parent, str
repsz = hid_report_size(desc, size, hid_input, repid);
DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
repsizes[repid] = repsz;
- if (repsz > 0) {
- if (repsz > sc->sc_isize)
- sc->sc_isize = repsz;
- }
+ if (repsz > sc->sc_isize)
+ sc->sc_isize = repsz;
}
- sc->sc_isize += nrepid != 1; /* space for report ID */
+ sc->sc_isize += (nrepid != 1); /* one byte for the report ID */
DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));
uha.uaa = uaa;
uha.parent = sc;
- for (repid = 0; repid < nrepid; repid++) {
- struct device *dev;
+ uha.reportid = UHIDEV_CLAIM_ALLREPORTID;
+
+ /* 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;
+ return;
+ }
+ for (repid = 0; repid < nrepid; repid++) {
DPRINTF(("%s: try repid=%d\n", __func__, repid));
if (hid_report_size(desc, size, hid_input, repid) == 0 &&
hid_report_size(desc, size, hid_output, repid) == 0 &&
@@ -315,7 +322,7 @@ uhidevprint(void *aux, const char *pnp)
if (pnp)
printf("uhid at %s", pnp);
- if (uha->reportid != 0)
+ if (uha->reportid != 0 && uha->reportid != UHIDEV_CLAIM_ALLREPORTID)
printf(" reportid %d", uha->reportid);
return (UNCONF);
}
@@ -356,7 +363,7 @@ int
uhidev_detach(struct device *self, int flags)
{
struct uhidev_softc *sc = (struct uhidev_softc *)self;
- int i, rv;
+ int i, rv = 0;
DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
@@ -375,7 +382,14 @@ uhidev_detach(struct device *self, int f
if (sc->sc_repdesc != NULL)
free(sc->sc_repdesc, M_USBDEV);
- rv = 0;
+ /*
+ * XXX Check if we have only one children claiming all the Report
+ * IDs, this is a hack since we need a dev -> Report ID mapping
+ * for uhidev_intr().
+ */
+ if (sc->sc_nrepid > 0 && sc->sc_subdevs[0] == sc->sc_subdevs[1])
+ return (config_detach(&sc->sc_subdevs[0]->sc_dev, flags));
+
for (i = 0; i < sc->sc_nrepid; i++) {
if (sc->sc_subdevs[i] != NULL) {
rv |= config_detach(&sc->sc_subdevs[i]->sc_dev, flags);
Index: dev/usb/uhidev.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhidev.h,v
retrieving revision 1.17
diff -u -p -r1.17 uhidev.h
--- dev/usb/uhidev.h 15 Mar 2014 09:50:26 -0000 1.17
+++ dev/usb/uhidev.h 17 Mar 2014 23:28:38 -0000
@@ -77,10 +77,10 @@ struct uhidev {
};
struct uhidev_attach_arg {
- struct usb_attach_arg *uaa;
- struct uhidev_softc *parent;
- int reportid;
- int reportsize;
+ struct usb_attach_arg *uaa;
+ struct uhidev_softc *parent;
+ uint8_t reportid;
+#define UHIDEV_CLAIM_ALLREPORTID 255
};
void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
Index: dev/usb/uoaklux.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uoaklux.c,v
retrieving revision 1.6
diff -u -p -r1.6 uoaklux.c
--- dev/usb/uoaklux.c 7 Mar 2014 18:39:02 -0000 1.6
+++ dev/usb/uoaklux.c 17 Mar 2014 23:28:38 -0000
@@ -106,8 +106,10 @@ struct uoak_methods uoaklux_methods = {
int
uoaklux_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
if (uoaklux_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
return UMATCH_NONE;
Index: dev/usb/uoakrh.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uoakrh.c,v
retrieving revision 1.7
diff -u -p -r1.7 uoakrh.c
--- dev/usb/uoakrh.c 7 Mar 2014 18:39:02 -0000 1.7
+++ dev/usb/uoakrh.c 17 Mar 2014 23:28:38 -0000
@@ -109,8 +109,10 @@ struct uoak_methods uoakrh_methods = {
int
uoakrh_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
if (uoakrh_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
return UMATCH_NONE;
Index: dev/usb/uoakv.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uoakv.c,v
retrieving revision 1.6
diff -u -p -r1.6 uoakv.c
--- dev/usb/uoakv.c 7 Mar 2014 18:39:02 -0000 1.6
+++ dev/usb/uoakv.c 17 Mar 2014 23:28:38 -0000
@@ -109,8 +109,10 @@ struct uoak_methods uoakv_methods = {
int
uoakv_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
if (uoakv_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
return UMATCH_NONE;
Index: dev/usb/usb_quirks.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v
retrieving revision 1.69
diff -u -p -r1.69 usb_quirks.c
--- dev/usb/usb_quirks.c 30 Oct 2013 12:28:19 -0000 1.69
+++ dev/usb/usb_quirks.c 17 Mar 2014 23:28:38 -0000
@@ -109,8 +109,6 @@ const struct usbd_quirk_entry {
{ USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY920, ANY, { UQ_BROKEN_BIDIR }},
{ USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY800, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_APC, USB_PRODUCT_APC_UPS, ANY, {
UQ_BAD_HID }},
- { USB_VENDOR_APC, USB_PRODUCT_APC_UPS5G, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3GS, ANY, { UQ_BAD_HID }},
@@ -147,7 +145,6 @@ const struct usbd_quirk_entry {
{ USB_VENDOR_HP, USB_PRODUCT_HP_T750G2, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_IDOWELL, USB_PRODUCT_IDOWELL_IDOWELL, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_ITUNER, USB_PRODUCT_ITUNER_USBLCD20x2, ANY, { UQ_BAD_HID }},
- { USB_VENDOR_LIEBERT, USB_PRODUCT_LIEBERT_UPS, ANY, {
UQ_BAD_HID }},
{ USB_VENDOR_LIEBERT2, USB_PRODUCT_LIEBERT2_PSA, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_MECANIQUE, USB_PRODUCT_MECANIQUE_WISPY, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24I, ANY, { UQ_BAD_HID }},
Index: dev/usb/uthum.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uthum.c,v
retrieving revision 1.25
diff -u -p -r1.25 uthum.c
--- dev/usb/uthum.c 7 Mar 2014 18:39:02 -0000 1.25
+++ dev/usb/uthum.c 17 Mar 2014 23:28:38 -0000
@@ -167,8 +167,10 @@ const struct cfattach uthum_ca = {
int
uthum_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
if (uthum_lookup(uha->uaa->vendor, uha->uaa->product) == NULL)
return UMATCH_NONE;
Index: dev/usb/utrh.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/utrh.c,v
retrieving revision 1.12
diff -u -p -r1.12 utrh.c
--- dev/usb/utrh.c 7 Mar 2014 18:39:02 -0000 1.12
+++ dev/usb/utrh.c 17 Mar 2014 23:28:38 -0000
@@ -92,8 +92,10 @@ const struct cfattach utrh_ca = {
int
utrh_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
return (usb_lookup(utrh_devs, uha->uaa->vendor, uha->uaa->product) !=
NULL ?
UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
Index: dev/usb/utwitch.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/utwitch.c,v
retrieving revision 1.9
diff -u -p -r1.9 utwitch.c
--- dev/usb/utwitch.c 7 Mar 2014 18:39:02 -0000 1.9
+++ dev/usb/utwitch.c 17 Mar 2014 23:28:38 -0000
@@ -107,8 +107,10 @@ const struct cfattach utwitch_ca = {
int
utwitch_match(struct device *parent, void *match, void *aux)
{
- struct usb_attach_arg *uaa = aux;
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ struct uhidev_attach_arg *uha = aux;
+
+ if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
+ return (UMATCH_NONE);
return (usb_lookup(utwitch_devs, uha->uaa->vendor, uha->uaa->product)
!= NULL ?
UMATCH_VENDOR_PRODUCT : UMATCH_NONE);