The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7699ec1558b7ec2224a4db992ab63aaa849b26fd

commit 7699ec1558b7ec2224a4db992ab63aaa849b26fd
Author:     Vladimir Kondratyev <[email protected]>
AuthorDate: 2025-08-17 21:00:44 +0000
Commit:     Vladimir Kondratyev <[email protected]>
CommitDate: 2025-08-17 21:00:44 +0000

    hid: Add HQ_NO_READAHEAD quirk and implement it in usbhid(4)
    
    It disables interrupt emulation on poll-driven buses like USB and
    forces aquiring of only one USB frame per read(2) operation.
    This avoids an FIDO/U2F issue where IN endpoint data received from
    the device right before the file handle is closed, gets lost.
    
    PR:             263995
    Reviewed by:    aokblast
    Differential revision:  https://reviews.freebsd.org/D51605
---
 sys/dev/hid/hidquirk.h     | 1 +
 sys/dev/usb/input/usbhid.c | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/sys/dev/hid/hidquirk.h b/sys/dev/hid/hidquirk.h
index 4f8b8acbe201..f6fa9f88c6c9 100644
--- a/sys/dev/hid/hidquirk.h
+++ b/sys/dev/hid/hidquirk.h
@@ -50,6 +50,7 @@
        HQ(IS_XBOX360GP),       /* device is XBox 360 GamePad */        \
        HQ(NOWRITE),            /* device does not support writes */    \
        HQ(IICHID_SAMPLING),    /* IIC backend runs in sampling mode */ \
+       HQ(NO_READAHEAD),       /* Disable interrupt after one report */\
                                                                        \
        /* Various quirks */                                            \
        HQ(HID_IGNORE),         /* device should be ignored by hid class */ \
diff --git a/sys/dev/usb/input/usbhid.c b/sys/dev/usb/input/usbhid.c
index df810012b3f8..255e639621fe 100644
--- a/sys/dev/usb/input/usbhid.c
+++ b/sys/dev/usb/input/usbhid.c
@@ -114,6 +114,7 @@ struct usbhid_xfer_ctx {
        void *cb_ctx;
        int waiters;
        bool influx;
+       bool no_readahead;
 };
 
 struct usbhid_softc {
@@ -272,7 +273,7 @@ usbhid_intr_handler_cb(struct usbhid_xfer_ctx *xfer_ctx)
        sc->sc_intr_handler(sc->sc_intr_ctx, xfer_ctx->buf,
            xfer_ctx->req.intr.actlen);
 
-       return (0);
+       return (xfer_ctx->no_readahead ? ECANCELED : 0);
 }
 
 static int
@@ -430,6 +431,7 @@ usbhid_intr_start(device_t dev, device_t child __unused)
                .cb = usbhid_intr_handler_cb,
                .cb_ctx = sc,
                .buf = sc->sc_intr_buf,
+               .no_readahead = hid_test_quirk(&sc->sc_hw, HQ_NO_READAHEAD),
        };
        sc->sc_xfer_ctx[POLL_XFER(USBHID_INTR_IN_DT)] = (struct 
usbhid_xfer_ctx) {
                .req.intr.maxlen =

Reply via email to