summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhidev.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/uhidev.c')
-rw-r--r--sys/dev/usb/uhidev.c93
1 files changed, 58 insertions, 35 deletions
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 84bcc4a2646..2dd88657444 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.c,v 1.63 2014/08/10 12:48:43 mpi Exp $ */
+/* $OpenBSD: uhidev.c,v 1.64 2014/12/08 22:00:11 mpi Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -264,12 +264,16 @@ int
uhidev_use_rdesc(struct uhidev_softc *sc, int vendor, int product,
void **descp, int *sizep)
{
- static uByte reportbuf[] = {2, 2, 2};
+ static uByte reportbuf[] = {2, 2};
const void *descptr = NULL;
void *desc;
int size;
if (vendor == USB_VENDOR_WACOM) {
+ struct uhidev wacom;
+
+ /* XXX until we pass the parent directly. */
+ wacom.sc_parent = sc;
/* The report descriptor for the Wacom Graphire is broken. */
switch (product) {
@@ -279,9 +283,8 @@ uhidev_use_rdesc(struct uhidev_softc *sc, int vendor, int product,
break;
case USB_PRODUCT_WACOM_GRAPHIRE3_4X5:
case USB_PRODUCT_WACOM_GRAPHIRE4_4X5:
- usbd_set_report(sc->sc_udev, sc->sc_ifaceno,
- UHID_FEATURE_REPORT, 2, &reportbuf,
- sizeof(reportbuf));
+ uhidev_set_report(&wacom, UHID_FEATURE_REPORT,
+ 2, &reportbuf, sizeof(reportbuf));
size = sizeof(uhid_graphire3_4x5_report_descr);
descptr = uhid_graphire3_4x5_report_descr;
break;
@@ -629,23 +632,30 @@ usbd_status
uhidev_set_report(struct uhidev *scd, int type, int id, void *data, int len)
{
struct uhidev_softc *sc = scd->sc_parent;
- char *buf;
- usbd_status retstat;
-
- if (id == 0)
- return usbd_set_report(sc->sc_udev, sc->sc_ifaceno, type,
- id, data, len);
+ usb_device_request_t req;
+ usbd_status err;
+ char *buf = data;
+
+ /* Prepend the reportID. */
+ if (id > 0) {
+ len++;
+ buf = malloc(len, M_TEMP, M_WAITOK);
+ buf[0] = id;
+ memcpy(buf + 1, data, len - 1);
+ }
- buf = malloc(len + 1, M_TEMP, M_WAITOK);
- buf[0] = id;
- memcpy(buf+1, data, len);
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
- retstat = usbd_set_report(sc->sc_udev, sc->sc_ifaceno, type,
- id, buf, len + 1);
+ err = usbd_do_request(sc->sc_udev, &req, buf);
- free(buf, M_TEMP, 0);
+ if (id > 0)
+ free(buf, M_TEMP, len);
- return retstat;
+ return (err);
}
usbd_status
@@ -653,39 +663,52 @@ uhidev_set_report_async(struct uhidev *scd, int type, int id, void *data,
int len)
{
struct uhidev_softc *sc = scd->sc_parent;
- char *buf;
- usbd_status retstat;
-
- if (id == 0)
- return usbd_set_report_async(sc->sc_udev, sc->sc_ifaceno, type,
- id, data, len);
+ usb_device_request_t req;
+ usbd_status err;
+ char *buf = data;
+
+ /* Prepend the reportID. */
+ if (id > 0) {
+ len++;
+ buf = malloc(len, M_TEMP, M_NOWAIT);
+ if (buf == NULL)
+ return (USBD_NOMEM);
+ buf[0] = id;
+ memcpy(buf + 1, data, len - 1);
+ }
- buf = malloc(len + 1, M_TEMP, M_NOWAIT);
- if (buf == NULL)
- return (USBD_NOMEM);
- buf[0] = id;
- memcpy(buf+1, data, len);
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UR_SET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
- retstat = usbd_set_report_async(sc->sc_udev, sc->sc_ifaceno, type,
- id, buf, len + 1);
+ err = usbd_do_request_async(sc->sc_udev, &req, buf);
/*
* Since report requests are write-only it is safe to free
* the buffer right after submitting the transfer because
* it won't be used afterward.
*/
- free(buf, M_TEMP, 0);
+ if (id > 0)
+ free(buf, M_TEMP, len);
- return retstat;
+ return (err);
}
usbd_status
uhidev_get_report(struct uhidev *scd, int type, int id, void *data, int len)
{
struct uhidev_softc *sc = scd->sc_parent;
+ usb_device_request_t req;
+
+ req.bmRequestType = UT_READ_CLASS_INTERFACE;
+ req.bRequest = UR_GET_REPORT;
+ USETW2(req.wValue, type, id);
+ USETW(req.wIndex, sc->sc_ifaceno);
+ USETW(req.wLength, len);
- return usbd_get_report(sc->sc_udev, sc->sc_ifaceno, type,
- id, data, len);
+ return (usbd_do_request(sc->sc_udev, &req, data));
}
usbd_status