summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhidev.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2013-11-01 12:05:27 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2013-11-01 12:05:27 +0000
commit1f302a5e30a7d416a32b6dfc8a3e63750069c3e5 (patch)
treedcca24cccca94c67996cc992acbbc0f63a228033 /sys/dev/usb/uhidev.c
parent8de4f21f9c368b1fdeaafe1e74718c25a926b29e (diff)
Do not abuse the stack of the current process to prepend a report ID
to the report request, use malloc(9) with the appropriate size like it is done in the synchronous version. ok miod@
Diffstat (limited to 'sys/dev/usb/uhidev.c')
-rw-r--r--sys/dev/usb/uhidev.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 341d08e2aca..0bf42b0b408 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.c,v 1.47 2013/10/25 03:09:59 jeremy Exp $ */
+/* $OpenBSD: uhidev.c,v 1.48 2013/11/01 12:05:26 mpi Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -611,27 +611,33 @@ uhidev_set_report(struct uhidev *scd, int type, void *data, int len)
return retstat;
}
-void
+usbd_status
uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len)
{
- /* XXX */
- char buf[100];
- if (scd->sc_report_id) {
- buf[0] = scd->sc_report_id;
- if ((uint)len > sizeof(buf) - 1) {
-#ifdef DIAGNOSTIC
- printf("%s: report length too large (%d)\n",
- scd->sc_dev.dv_xname, len);
-#endif
- return;
- }
- memcpy(buf+1, data, len);
- len++;
- data = buf;
- }
+ char *buf;
+ usbd_status retstat;
+
+ if (scd->sc_report_id == 0)
+ return usbd_set_report_async(scd->sc_parent->sc_iface, type,
+ scd->sc_report_id, data, len);
+
+ buf = malloc(len + 1, M_TEMP, M_NOWAIT);
+ if (buf == NULL)
+ return (USBD_NOMEM);
+ buf[0] = scd->sc_report_id;
+ memcpy(buf+1, data, len);
+
+ retstat = usbd_set_report_async(scd->sc_parent->sc_iface, type,
+ scd->sc_report_id, buf, len + 1);
- usbd_set_report_async(scd->sc_parent->sc_iface, type,
- scd->sc_report_id, data, len);
+ /*
+ * 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);
+
+ return retstat;
}
usbd_status