diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-11-01 12:05:27 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-11-01 12:05:27 +0000 |
commit | 1f302a5e30a7d416a32b6dfc8a3e63750069c3e5 (patch) | |
tree | dcca24cccca94c67996cc992acbbc0f63a228033 /sys/dev/usb/uhidev.c | |
parent | 8de4f21f9c368b1fdeaafe1e74718c25a926b29e (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.c | 44 |
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 |