Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Stop crash when switching vt or leaving X windows.
details: https://anonhg.NetBSD.org/src/rev/61289c10bbdc
branches: trunk
changeset: 348440:61289c10bbdc
user: nat <nat%NetBSD.org@localhost>
date: Tue Oct 18 20:17:37 2016 +0000
description:
Stop crash when switching vt or leaving X windows.
Improved upon and OK from christos@
diffstat:
sys/dev/usb/udl.c | 32 ++++++++++++++++++++++++++------
sys/dev/usb/udl.h | 3 ++-
2 files changed, 28 insertions(+), 7 deletions(-)
diffs (135 lines):
diff -r 6cac02a13479 -r 61289c10bbdc sys/dev/usb/udl.c
--- a/sys/dev/usb/udl.c Tue Oct 18 18:56:39 2016 +0000
+++ b/sys/dev/usb/udl.c Tue Oct 18 20:17:37 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udl.c,v 1.16 2016/10/17 20:04:48 nat Exp $ */
+/* $NetBSD: udl.c,v 1.17 2016/10/18 20:17:37 nat Exp $ */
/*-
* Copyright (c) 2009 FUKAUMI Naoki.
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udl.c,v 1.16 2016/10/17 20:04:48 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udl.c,v 1.17 2016/10/18 20:17:37 nat Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -175,6 +175,7 @@
const struct videomode *);
static const struct videomode *udl_videomode_lookup(const char *);
static void udl_update_thread(void *);
+static inline void udl_startstop(struct udl_softc *, bool);
static inline void
udl_cmd_add_1(struct udl_softc *sc, uint8_t val)
@@ -475,6 +476,7 @@
mutex_init(&sc->sc_thread_mtx, MUTEX_DEFAULT, IPL_NONE);
cv_init(&sc->sc_thread_cv, "udlcv");
sc->sc_dying = false;
+ sc->sc_thread_stop = true;
kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,
udl_update_thread, sc, &sc->sc_thread, "udlupd");
}
@@ -511,8 +513,10 @@
*/
udl_fbmem_free(sc);
+ mutex_enter(&sc->sc_thread_mtx);
sc->sc_dying = true;
cv_broadcast(&sc->sc_thread_cv);
+ mutex_exit(&sc->sc_thread_mtx);
kthread_join(sc->sc_thread);
cv_destroy(&sc->sc_cv);
@@ -571,6 +575,7 @@
return 0;
switch (mode) {
case WSDISPLAYIO_VIDEO_OFF:
+ udl_startstop(sc, true);
udl_blank(sc, 1);
break;
case WSDISPLAYIO_VIDEO_ON:
@@ -579,7 +584,8 @@
default:
return EINVAL;
}
- udl_cmd_send_async(sc);
+ if (UDL_CMD_BUFSIZE(sc) > 0)
+ udl_cmd_send_async(sc);
udl_cmdq_flush(sc);
sc->sc_blank = mode;
return 0;
@@ -590,10 +596,12 @@
return 0;
switch (mode) {
case WSDISPLAYIO_MODE_EMUL:
+ udl_startstop(sc, true);
/* clear screen */
udl_fill_rect(sc, 0, 0, 0, sc->sc_width,
sc->sc_height);
- udl_cmd_send_async(sc);
+ if (UDL_CMD_BUFSIZE(sc) > 0)
+ udl_cmd_send_async(sc);
udl_cmdq_flush(sc);
udl_comp_unload(sc);
break;
@@ -602,6 +610,7 @@
udl_cmd_send_async(sc);
udl_cmdq_flush(sc);
udl_comp_load(sc);
+ udl_startstop(sc, false);
break;
default:
return EINVAL;
@@ -652,7 +661,8 @@
if (udl_fbmem_alloc(sc) != 0)
return -1;
- cv_broadcast(&sc->sc_thread_cv);
+ udl_startstop(sc, false);
+
vaddr = (vaddr_t)sc->sc_fbmem + off;
rv = pmap_extract(pmap_kernel(), vaddr, &paddr);
KASSERT(rv);
@@ -1823,7 +1833,7 @@
kthread_exit(0);
}
- if (sc->sc_fbmem == NULL)
+ if (sc->sc_thread_stop == true || sc->sc_fbmem == NULL)
goto thread_wait;
#ifdef notyet
@@ -1877,3 +1887,13 @@
cv_wait(&sc->sc_thread_cv, &sc->sc_thread_mtx);
}
}
+
+static inline void
+udl_startstop(struct udl_softc *sc, bool stop)
+{
+ mutex_enter(&sc->sc_thread_mtx);
+ sc->sc_thread_stop = stop;
+ if (!stop)
+ cv_broadcast(&sc->sc_thread_cv);
+ mutex_exit(&sc->sc_thread_mtx);
+}
diff -r 6cac02a13479 -r 61289c10bbdc sys/dev/usb/udl.h
--- a/sys/dev/usb/udl.h Tue Oct 18 18:56:39 2016 +0000
+++ b/sys/dev/usb/udl.h Tue Oct 18 20:17:37 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udl.h,v 1.3 2016/10/17 20:04:48 nat Exp $ */
+/* $NetBSD: udl.h,v 1.4 2016/10/18 20:17:37 nat Exp $ */
/*-
* Copyright (c) 2009 FUKAUMI Naoki.
@@ -119,6 +119,7 @@
kcondvar_t sc_thread_cv;
kmutex_t sc_thread_mtx;
bool sc_dying;
+ bool sc_thread_stop;
lwp_t *sc_thread;
kcondvar_t sc_cv;
Home |
Main Index |
Thread Index |
Old Index