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