From 8565b6d4ed3b861e3aeb9c080cb88384aae483e8 Mon Sep 17 00:00:00 2001 From: jcs Date: Wed, 24 Mar 2021 02:49:57 +0000 Subject: [PATCH] Define a USB quirk for devices that need to keep their pipes open at all times, before the device is enabled and after the device is disabled by wscons. This was originally needed by umt for the Microsoft Surface Type Cover to avoid it resetting (or at least detaching and reattaching) when the touchpad was touched while at the console. A similar problem occurs with the Pinebook Pro's keyboard when switching from X to the console due to the touchpad getting disabled, so add it to ums as well. with and ok kurt --- sys/dev/usb/ums.c | 36 +++++++++++++++++++++++++++--------- sys/dev/usb/umt.c | 28 +++++++++++++++++++++++++--- sys/dev/usb/usb_quirks.c | 10 +++++++++- sys/dev/usb/usb_quirks.h | 3 ++- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c index 15c777c85a8..bd34bcea1f1 100644 --- a/sys/dev/usb/ums.c +++ b/sys/dev/usb/ums.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ums.c,v 1.47 2021/01/29 16:59:41 sthen Exp $ */ +/* $OpenBSD: ums.c,v 1.48 2021/03/24 02:49:57 jcs Exp $ */ /* $NetBSD: ums.c,v 1.60 2003/03/11 16:44:00 augustss Exp $ */ /* @@ -58,6 +58,7 @@ struct ums_softc { struct uhidev sc_hdev; struct hidms sc_ms; + uint32_t sc_quirks; }; void ums_intr(struct uhidev *addr, void *ibuf, u_int len); @@ -122,7 +123,7 @@ ums_attach(struct device *parent, struct device *self, void *aux) struct usb_attach_arg *uaa = uha->uaa; int size, repid; void *desc; - u_int32_t quirks, qflags = 0; + u_int32_t qflags = 0; sc->sc_hdev.sc_intr = ums_intr; sc->sc_hdev.sc_parent = uha->parent; @@ -131,7 +132,7 @@ ums_attach(struct device *parent, struct device *self, void *aux) usbd_set_idle(uha->parent->sc_udev, uha->parent->sc_ifaceno, 0, 0); - quirks = usbd_get_quirks(sc->sc_hdev.sc_udev)->uq_flags; + sc->sc_quirks = usbd_get_quirks(sc->sc_hdev.sc_udev)->uq_flags; uhidev_get_report_desc(uha->parent, &desc, &size); if (uaa->vendor == USB_VENDOR_ELECOM) @@ -142,15 +143,15 @@ ums_attach(struct device *parent, struct device *self, void *aux) sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid); sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid); - if (quirks & UQ_MS_REVZ) + if (sc->sc_quirks & UQ_MS_REVZ) qflags |= HIDMS_REVZ; - if (quirks & UQ_SPUR_BUT_UP) + if (sc->sc_quirks & UQ_SPUR_BUT_UP) qflags |= HIDMS_SPUR_BUT_UP; - if (quirks & UQ_MS_BAD_CLASS) + if (sc->sc_quirks & UQ_MS_BAD_CLASS) qflags |= HIDMS_MS_BAD_CLASS; - if (quirks & UQ_MS_LEADING_BYTE) + if (sc->sc_quirks & UQ_MS_LEADING_BYTE) qflags |= HIDMS_LEADINGBYTE; - if (quirks & UQ_MS_VENDOR_BUTTONS) + if (sc->sc_quirks & UQ_MS_VENDOR_BUTTONS) qflags |= HIDMS_VENDOR_BUTTONS; if (hidms_setup(self, ms, qflags, uha->reportid, desc, size) != 0) @@ -177,6 +178,13 @@ ums_attach(struct device *parent, struct device *self, void *aux) } hidms_attach(ms, &ums_accessops); + + if (sc->sc_quirks & UQ_ALWAYS_OPEN) { + /* open uhidev and keep it open */ + ums_enable(sc); + /* but mark the hidms not in use */ + ums_disable(sc); + } } int @@ -211,7 +219,13 @@ ums_enable(void *v) if ((rv = hidms_enable(ms)) != 0) return rv; - return uhidev_open(&sc->sc_hdev); + if ((sc->sc_quirks & UQ_ALWAYS_OPEN) && + (sc->sc_hdev.sc_state & UHIDEV_OPEN)) + rv = 0; + else + rv = uhidev_open(&sc->sc_hdev); + + return rv; } void @@ -221,6 +235,10 @@ ums_disable(void *v) struct hidms *ms = &sc->sc_ms; hidms_disable(ms); + + if (sc->sc_quirks & UQ_ALWAYS_OPEN) + return; + uhidev_close(&sc->sc_hdev); } diff --git a/sys/dev/usb/umt.c b/sys/dev/usb/umt.c index a3fd5ce9c28..3aa45bf298a 100644 --- a/sys/dev/usb/umt.c +++ b/sys/dev/usb/umt.c @@ -1,9 +1,9 @@ -/* $OpenBSD: umt.c,v 1.3 2021/03/08 14:35:57 jcs Exp $ */ +/* $OpenBSD: umt.c,v 1.4 2021/03/24 02:49:57 jcs Exp $ */ /* * USB multitouch touchpad driver for devices conforming to * Windows Precision Touchpad standard * - * https://msdn.microsoft.com/en-us/library/windows/hardware/dn467314%28v=vs.85%29.aspx + * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections * * Copyright (c) 2016-2018 joshua stein * @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,8 @@ struct umt_softc { int sc_rep_input; int sc_rep_config; int sc_rep_cap; + + u_int32_t sc_quirks; }; int umt_enable(void *); @@ -151,14 +154,18 @@ umt_attach(struct device *parent, struct device *self, void *aux) struct umt_softc *sc = (struct umt_softc *)self; struct hidmt *mt = &sc->sc_mt; struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; + struct usb_attach_arg *uaa = uha->uaa; int size; void *desc; sc->sc_hdev.sc_intr = umt_intr; sc->sc_hdev.sc_parent = uha->parent; + sc->sc_hdev.sc_udev = uaa->device; usbd_set_idle(uha->parent->sc_udev, uha->parent->sc_ifaceno, 0, 0); + sc->sc_quirks = usbd_get_quirks(sc->sc_hdev.sc_udev)->uq_flags; + uhidev_get_report_desc(uha->parent, &desc, &size); umt_find_winptp_reports(uha->parent, desc, size, &sc->sc_rep_input, &sc->sc_rep_config, &sc->sc_rep_cap); @@ -179,6 +186,13 @@ umt_attach(struct device *parent, struct device *self, void *aux) return; hidmt_attach(mt, &umt_accessops); + + if (sc->sc_quirks & UQ_ALWAYS_OPEN) { + /* open uhidev and keep it open */ + umt_enable(sc); + /* but mark the hidmt not in use */ + umt_disable(sc); + } } int @@ -232,7 +246,11 @@ umt_enable(void *v) if ((rv = hidmt_enable(mt)) != 0) return rv; - rv = uhidev_open(&sc->sc_hdev); + if ((sc->sc_quirks & UQ_ALWAYS_OPEN) && + (sc->sc_hdev.sc_state & UHIDEV_OPEN)) + rv = 0; + else + rv = uhidev_open(&sc->sc_hdev); hidmt_set_input_mode(mt, HIDMT_INPUT_MODE_MT_TOUCHPAD); @@ -246,6 +264,10 @@ umt_disable(void *v) struct hidmt *mt = &sc->sc_mt; hidmt_disable(mt); + + if (sc->sc_quirks & UQ_ALWAYS_OPEN) + return; + uhidev_close(&sc->sc_hdev); } diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c index bd465526a40..be65ad08602 100644 --- a/sys/dev/usb/usb_quirks.c +++ b/sys/dev/usb/usb_quirks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_quirks.c,v 1.77 2021/01/10 16:32:48 thfr Exp $ */ +/* $OpenBSD: usb_quirks.c,v 1.78 2021/03/24 02:49:57 jcs Exp $ */ /* $NetBSD: usb_quirks.c,v 1.45 2003/05/10 17:47:14 hamajima Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */ @@ -153,6 +153,14 @@ const struct usbd_quirk_entry { { USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_SLIMBLADE, ANY, { UQ_MS_VENDOR_BUTTONS }}, +/* Devices that need their data pipe held open */ + { USB_VENDOR_HAILUCK, USB_PRODUCT_HAILUCK_KEYBOARD, + ANY, { UQ_ALWAYS_OPEN }}, + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER, + ANY, { UQ_ALWAYS_OPEN }}, + { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TYPECOVER2, + ANY, { UQ_ALWAYS_OPEN }}, + { 0, 0, 0, { 0 } } }; diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h index bb751f7af51..86024a8f3ae 100644 --- a/sys/dev/usb/usb_quirks.h +++ b/sys/dev/usb/usb_quirks.h @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_quirks.h,v 1.17 2021/01/10 16:32:48 thfr Exp $ */ +/* $OpenBSD: usb_quirks.h,v 1.18 2021/03/24 02:49:57 jcs Exp $ */ /* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */ @@ -51,6 +51,7 @@ struct usbd_quirks { if attached to EHCI */ #define UQ_MS_VENDOR_BUTTONS 0x00040000 /* mouse reports extra buttons in vendor page */ +#define UQ_ALWAYS_OPEN 0x00080000 /* always keep data pipe open */ }; extern const struct usbd_quirks usbd_no_quirk; -- 2.20.1