summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2020-09-14 15:21:08 +0000
committerderaadt <deraadt@openbsd.org>2020-09-14 15:21:08 +0000
commitf64b4d9d126d6312d4a05f860dd8fd566273e4c2 (patch)
tree6a1a013eb51b4908eb1bce52ed3a66c9f652635c
parentAllow snmp mibtree to take one or more arguments who will be converted to (diff)
downloadwireguard-openbsd-f64b4d9d126d6312d4a05f860dd8fd566273e4c2.tar.xz
wireguard-openbsd-f64b4d9d126d6312d4a05f860dd8fd566273e4c2.zip
umstc_intr is not in process context when adjusting wscons brightness. When brightness
is pushed to 0, the backlight is disabled by some backend code which happens to sleep. Solve this by bouncing to process context via a task. ok kettenis
-rw-r--r--sys/dev/usb/umstc.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/sys/dev/usb/umstc.c b/sys/dev/usb/umstc.c
index bb992757a03..71cd2d2b829 100644
--- a/sys/dev/usb/umstc.c
+++ b/sys/dev/usb/umstc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: umstc.c,v 1.2 2020/08/23 11:08:02 mglocker Exp $ */
+/* $OpenBSD: umstc.c,v 1.3 2020/09/14 15:21:08 deraadt Exp $ */
/*
* Copyright (c) 2020 joshua stein <jcs@jcs.org>
@@ -26,6 +26,8 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
+#include <sys/atomic.h>
+#include <sys/task.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>
@@ -41,13 +43,16 @@
#include "wsdisplay.h"
struct umstc_softc {
- struct uhidev sc_hdev;
+ struct uhidev sc_hdev;
+ struct task sc_brightness_task;
+ int sc_brightness_steps;
};
void umstc_intr(struct uhidev *addr, void *ibuf, u_int len);
int umstc_match(struct device *, void *, void *);
void umstc_attach(struct device *, struct device *, void *);
int umstc_detach(struct device *, int flags);
+void umstc_brightness_task(void *);
extern int wskbd_set_mixervolume(long, long);
@@ -110,6 +115,8 @@ umstc_attach(struct device *parent, struct device *self, void *aux)
uhidev_open(&sc->sc_hdev);
+ task_set(&sc->sc_brightness_task, umstc_brightness_task, sc);
+
printf("\n");
}
@@ -118,6 +125,8 @@ umstc_detach(struct device *self, int flags)
{
struct umstc_softc *sc = (struct umstc_softc *)self;
+ task_del(systq, &sc->sc_brightness_task);
+
uhidev_close(&sc->sc_hdev);
return 0;
@@ -156,12 +165,14 @@ umstc_intr(struct uhidev *addr, void *buf, u_int len)
break;
case 0x70: /* brightness down */
#if NWSDISPLAY > 0
- wsdisplay_brightness_step(NULL, -1);
+ atomic_sub_int(&sc->sc_brightness_steps, 1);
+ task_add(systq, &sc->sc_brightness_task);
#endif
break;
case 0x6f: /* brightness up */
#if NWSDISPLAY > 0
- wsdisplay_brightness_step(NULL, 1);
+ atomic_add_int(&sc->sc_brightness_steps, 1);
+ task_add(systq, &sc->sc_brightness_task);
#endif
break;
case 0:
@@ -173,3 +184,19 @@ umstc_intr(struct uhidev *addr, void *buf, u_int len)
printf("\n");
}
}
+
+void
+umstc_brightness_task(void *arg)
+{
+ struct umstc_softc *sc = arg;
+ int steps = atomic_swap_uint(&sc->sc_brightness_steps, 0);
+ int dir = 1;
+
+ if (steps < 0) {
+ steps = -steps;
+ dir = -1;
+ }
+
+ while (steps--)
+ wsdisplay_brightness_step(NULL, dir);
+}