-/* $OpenBSD: uhidev.c,v 1.66 2014/12/13 21:05:33 doug Exp $ */
+/* $OpenBSD: uhidev.c,v 1.67 2015/01/09 12:07:50 mpi Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
#include <sys/ioctl.h>
#include <sys/conf.h>
+#include <machine/bus.h>
+
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdivar.h>
#include <dev/usb/hid.h>
#include <dev/usb/usb_quirks.h>
#define DPRINTFN(n,x)
#endif
+struct uhidev_async_info {
+ void (*callback)(void *priv, int id, void *data, int len);
+ void *priv;
+ void *data;
+ int id;
+};
+
void uhidev_intr(struct usbd_xfer *, void *, usbd_status);
int uhidev_maxrepid(void *buf, int len);
int uhidev_detach(struct device *, int);
int uhidev_activate(struct device *, int);
+void uhidev_get_report_async_cb(struct usbd_xfer *xfer, void *priv,
+ usbd_status status);
+
struct cfdriver uhidev_cd = {
NULL, "uhidev", DV_DULL
};
USETW(req.wIndex, sc->sc_ifaceno);
USETW(req.wLength, len);
- if (usbd_do_request_async(sc->sc_udev, &req, buf))
+ if (usbd_do_request_async(sc->sc_udev, &req, buf, NULL, NULL))
actlen = -1;
/*
return (actlen);
}
+void
+uhidev_get_report_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status err)
+{
+ struct uhidev_async_info *info = priv;
+ int len = -1;
+
+ if (err == USBD_NORMAL_COMPLETION || err == USBD_SHORT_XFER) {
+ len = xfer->actlen;
+ if (info->id > 0) {
+ len--;
+ memcpy(info->data, xfer->buffer + 1, 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);
+}
+
+int
+uhidev_get_report_async(struct uhidev_softc *sc, int type, int id, void *data,
+ int len, void *priv, void (*callback)(void *, int, void *, int))
+{
+ usb_device_request_t req;
+ struct uhidev_async_info *info;
+ char *buf = data;
+ int actlen = len;
+
+ info = malloc(sizeof(*info), M_TEMP, M_NOWAIT);
+ if (info == NULL)
+ 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)) {
+ free(info, M_TEMP, sizeof(*info));
+ if (id > 0)
+ free(buf, M_TEMP, len);
+ actlen = -1;
+ }
+ return (actlen);
+}
+
usbd_status
uhidev_write(struct uhidev_softc *sc, void *data, int len)
{
-/* $OpenBSD: uhidev.h,v 1.21 2014/12/11 18:39:27 mpi Exp $ */
+/* $OpenBSD: uhidev.h,v 1.22 2015/01/09 12:07:50 mpi Exp $ */
/* $NetBSD: uhidev.h,v 1.3 2002/10/08 09:56:17 dan Exp $ */
/*
int uhidev_set_report(struct uhidev_softc *, int, int, void *, int);
int uhidev_set_report_async(struct uhidev_softc *, int, int, void *, int);
int uhidev_get_report(struct uhidev_softc *, int, int, void *, int);
+int uhidev_get_report_async(struct uhidev_softc *, int, int, void *, int,
+ void *, void (*)(void *, int, void *, int));
usbd_status uhidev_write(struct uhidev_softc *, void *, int);
-/* $OpenBSD: usbdi.c,v 1.75 2014/11/01 00:41:33 mpi Exp $ */
+/* $OpenBSD: usbdi.c,v 1.76 2015/01/09 12:07:50 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 $ */
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);
+ err = usbd_do_request_async(dev, &req, 0, 0, 0);
return (err);
}
*/
usbd_status
usbd_do_request_async(struct usbd_device *dev, usb_device_request_t *req,
- void *data)
+ void *data, void *priv, usbd_callback callback)
{
struct usbd_xfer *xfer;
usbd_status err;
xfer = usbd_alloc_xfer(dev);
if (xfer == NULL)
return (USBD_NOMEM);
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
- data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
+ 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);
err = usbd_transfer(xfer);
if (err != USBD_IN_PROGRESS) {
usbd_free_xfer(xfer);
-/* $OpenBSD: usbdi.h,v 1.63 2014/08/10 11:18:57 mpi Exp $ */
+/* $OpenBSD: usbdi.h,v 1.64 2015/01/09 12:07:50 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 $ */
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);
+ usb_device_request_t *req, void *data, 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(