summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorJoshua Stein <jcs@cvs.openbsd.org>2021-03-24 02:49:58 +0000
committerJoshua Stein <jcs@cvs.openbsd.org>2021-03-24 02:49:58 +0000
commit5586b69a3b9cff5aed548be78e6ab007c52e7ab4 (patch)
tree6e8675a6ac8d7a9a8cb8c4e3588127455c69486d /sys/dev/usb
parent0bbe132ed43244c1c0ed1d1e3705ca2e93a0ef8b (diff)
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
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/ums.c36
-rw-r--r--sys/dev/usb/umt.c28
-rw-r--r--sys/dev/usb/usb_quirks.c10
-rw-r--r--sys/dev/usb/usb_quirks.h3
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 <jcs@openbsd.org>
*
@@ -31,6 +31,7 @@
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
+#include <dev/usb/usb_quirks.h>
#include <dev/usb/uhidev.h>
#include <dev/wscons/wsconsio.h>
@@ -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;