-/* $OpenBSD: uhidev.c,v 1.68 2015/01/09 12:09:51 mpi Exp $ */
+/* $OpenBSD: uhidev.c,v 1.69 2015/01/22 10:27:47 mpi Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
uhidev_set_report_async(struct uhidev_softc *sc, int type, int id, void *data,
int len)
{
+ struct usbd_xfer *xfer;
usb_device_request_t req;
- char *buf = data;
int actlen = len;
+ char *buf;
+
+ xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (xfer == NULL)
+ return (-1);
+
+ if (id > 0)
+ len++;
+
+ buf = usbd_alloc_buffer(xfer, len);
+ if (buf == NULL) {
+ usbd_free_xfer(xfer);
+ return (-1);
+ }
/* Prepend the reportID. */
if (id > 0) {
- len++;
- buf = malloc(len, M_TEMP, M_NOWAIT);
- if (buf == NULL)
- return (-1);
buf[0] = id;
memcpy(buf + 1, data, len - 1);
+ } else {
+ memcpy(buf, data, len);
}
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
USETW(req.wIndex, sc->sc_ifaceno);
USETW(req.wLength, len);
- if (usbd_do_request_async(sc->sc_udev, &req, buf, NULL, NULL))
+ if (usbd_request_async(xfer, &req, NULL, NULL))
actlen = -1;
- /*
- * 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.
- */
- if (id > 0)
- free(buf, M_TEMP, len);
-
return (actlen);
}
if (info->id > 0) {
len--;
memcpy(info->data, xfer->buffer + 1, len);
+ } else {
+ memcpy(info->data, xfer->buffer, len);
}
}
info->callback(info->priv, info->id, info->data, len);
- if (info->id > 0)
- free(xfer->buffer, M_TEMP, xfer->length);
free(info, M_TEMP, sizeof(*info));
usbd_free_xfer(xfer);
}
uhidev_get_report_async(struct uhidev_softc *sc, int type, int id, void *data,
int len, void *priv, void (*callback)(void *, int, void *, int))
{
+ struct usbd_xfer *xfer;
usb_device_request_t req;
struct uhidev_async_info *info;
- char *buf = data;
int actlen = len;
+ char *buf;
+
+ xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (xfer == NULL)
+ return (-1);
+
+ if (id > 0)
+ len++;
+
+ buf = usbd_alloc_buffer(xfer, len);
+ if (buf == NULL) {
+ usbd_free_xfer(xfer);
+ return (-1);
+ }
info = malloc(sizeof(*info), M_TEMP, M_NOWAIT);
- if (info == NULL)
+ if (info == NULL) {
+ usbd_free_xfer(xfer);
return (-1);
+ }
info->callback = callback;
info->priv = priv;
info->data = data;
info->id = id;
- if (id > 0) {
- len++;
- buf = malloc(len, M_TEMP, M_NOWAIT|M_ZERO);
- if (buf == NULL) {
- free(info, M_TEMP, sizeof(*info));
- return (-1);
- }
- }
-
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);
- if (usbd_do_request_async(sc->sc_udev, &req, buf, priv,
- uhidev_get_report_async_cb)) {
+ if (usbd_request_async(xfer, &req, priv, uhidev_get_report_async_cb)) {
free(info, M_TEMP, sizeof(*info));
- if (id > 0)
- free(buf, M_TEMP, len);
actlen = -1;
}
+
return (actlen);
}
-/* $OpenBSD: usbdi.c,v 1.78 2015/01/11 15:41:16 mpi Exp $ */
+/* $OpenBSD: usbdi.c,v 1.79 2015/01/22 10:27:47 mpi Exp $ */
/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
#define DPRINTFN(n,x)
#endif
-void usbd_do_request_async_cb(struct usbd_xfer *, void *,
- usbd_status);
+void usbd_request_async_cb(struct usbd_xfer *, void *, usbd_status);
void usbd_start_next(struct usbd_pipe *pipe);
usbd_status usbd_open_pipe_ival(struct usbd_interface *, u_int8_t, u_int8_t,
struct usbd_pipe **, int);
usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe)
{
struct usbd_device *dev = pipe->device;
+ struct usbd_xfer *xfer;
usb_device_request_t req;
usbd_status err;
USETW(req.wValue, UF_ENDPOINT_HALT);
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
USETW(req.wLength, 0);
- err = usbd_do_request_async(dev, &req, 0, 0, 0);
+
+ xfer = usbd_alloc_xfer(dev);
+ if (xfer == NULL)
+ return (USBD_NOMEM);
+
+ err = usbd_request_async(xfer, &req, NULL, NULL);
return (err);
}
}
void
-usbd_do_request_async_cb(struct usbd_xfer *xfer, void *priv,
- usbd_status status)
+usbd_request_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
usbd_free_xfer(xfer);
}
* Can be used from interrupt context.
*/
usbd_status
-usbd_do_request_async(struct usbd_device *dev, usb_device_request_t *req,
- void *data, void *priv, usbd_callback callback)
+usbd_request_async(struct usbd_xfer *xfer, usb_device_request_t *req,
+ void *priv, usbd_callback callback)
{
- struct usbd_xfer *xfer;
usbd_status err;
- xfer = usbd_alloc_xfer(dev);
- if (xfer == NULL)
- return (USBD_NOMEM);
if (callback == NULL)
- callback = usbd_do_request_async_cb;
- usbd_setup_default_xfer(xfer, dev, priv, USBD_DEFAULT_TIMEOUT, req,
- data, UGETW(req->wLength), 0, callback);
+ callback = usbd_request_async_cb;
+
+ usbd_setup_default_xfer(xfer, xfer->device, priv,
+ USBD_DEFAULT_TIMEOUT, req, NULL, UGETW(req->wLength),
+ USBD_NO_COPY, callback);
err = usbd_transfer(xfer);
if (err != USBD_IN_PROGRESS) {
usbd_free_xfer(xfer);
-/* $OpenBSD: usbdi.h,v 1.64 2015/01/09 12:07:50 mpi Exp $ */
+/* $OpenBSD: usbdi.h,v 1.65 2015/01/22 10:27:47 mpi Exp $ */
/* $NetBSD: usbdi.h,v 1.62 2002/07/11 21:14:35 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
void *buffer, u_int32_t length, usbd_callback, int);
usbd_status usbd_do_request(struct usbd_device *pipe, usb_device_request_t *req,
void *data);
-usbd_status usbd_do_request_async(struct usbd_device *pipe,
- usb_device_request_t *req, void *data, void *priv, usbd_callback callback);
+usbd_status usbd_request_async(struct usbd_xfer *xfer,
+ usb_device_request_t *req, void *priv, usbd_callback callback);
usbd_status usbd_do_request_flags(struct usbd_device *pipe,
usb_device_request_t *req, void *data, u_int16_t flags, int*, u_int32_t);
usb_interface_descriptor_t *usbd_get_interface_descriptor(