Module Name:    src
Committed By:   nat
Date:           Tue Oct 18 20:17:37 UTC 2016

Modified Files:
        src/sys/dev/usb: udl.c udl.h

Log Message:
Stop crash when switching vt or leaving X windows.

Improved upon and OK from christos@


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/usb/udl.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/usb/udl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/udl.c
diff -u src/sys/dev/usb/udl.c:1.16 src/sys/dev/usb/udl.c:1.17
--- src/sys/dev/usb/udl.c:1.16	Mon Oct 17 20:04:48 2016
+++ src/sys/dev/usb/udl.c	Tue Oct 18 20:17:37 2016
@@ -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 @@ static int		udl_set_resolution(struct ud
 			    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 @@ udl_attach(device_t parent, device_t sel
 	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_detach(device_t self, int flags)
 	 */
 	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 @@ udl_ioctl(void *v, void *vs, u_long cmd,
 			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 @@ udl_ioctl(void *v, void *vs, u_long cmd,
 		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 @@ udl_ioctl(void *v, void *vs, u_long cmd,
 			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_ioctl(void *v, void *vs, u_long cmd,
 				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 @@ udl_mmap(void *v, void *vs, off_t off, i
 	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 @@ udl_update_thread(void *v)
 			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 @@ thread_wait:
 		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);
+}

Index: src/sys/dev/usb/udl.h
diff -u src/sys/dev/usb/udl.h:1.3 src/sys/dev/usb/udl.h:1.4
--- src/sys/dev/usb/udl.h:1.3	Mon Oct 17 20:04:48 2016
+++ src/sys/dev/usb/udl.h	Tue Oct 18 20:17:37 2016
@@ -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 @@ struct udl_softc {
 	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;

Reply via email to