summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2020-08-27 17:33:08 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2020-08-27 17:33:08 +0000
commit9d82481c587f3bec98fb94de0070e54a040a38d0 (patch)
tree590b05a72fe211a63f421d24be5d44703323c2ce /sys
parent40a5c1c6a6f2ef40a921bf261bb7318bfc7aa5d2 (diff)
Clear endpoint stall on open(2) of /dev/uhidX to synchronize toggle bit
as needed on xhci(4) machines. On non-xhci(4) we save and restore the toggle bit on close/open of a pipe. With xhci(4) this does not seem to be possible, at least I haven't yet found it. This means that on those machines with xhci(4), after a pipe close/open, the device will use the previous state, while xhci(4)'s state is reset to default. By issuing a clear endpoint stall we reset the device's toggle bit. Now every time a /dev/uhid is (re-)opened the state should be synchronized. Discussed with damien@, mpi@ and Pedro Marteletto ok markus@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/uhidev.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index a7ce8de649d..e086a8d9251 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.c,v 1.81 2020/08/23 11:08:02 mglocker Exp $ */
+/* $OpenBSD: uhidev.c,v 1.82 2020/08/27 17:33:07 patrick Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -517,6 +517,7 @@ uhidev_open(struct uhidev *scd)
error = EIO;
goto out1;
}
+ usbd_clear_endpoint_stall(sc->sc_ipipe);
DPRINTF(("uhidev_open: sc->sc_ipipe=%p\n", sc->sc_ipipe));
@@ -536,13 +537,14 @@ uhidev_open(struct uhidev *scd)
err = usbd_open_pipe(sc->sc_iface, sc->sc_oep_addr,
0, &sc->sc_opipe);
-
if (err != USBD_NORMAL_COMPLETION) {
DPRINTF(("uhidev_open: usbd_open_pipe failed, "
"error=%d\n", err));
error = EIO;
goto out2;
}
+ usbd_clear_endpoint_stall(sc->sc_opipe);
+
DPRINTF(("uhidev_open: sc->sc_opipe=%p\n", sc->sc_opipe));
sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);