Subject: wsmux vs wsmouse open problems
To: None <tech-kern@netbsd.org>
From: Julio Merino <jmmv@menta.net>
List: tech-kern
Date: 05/04/2003 14:08:19
Hi all,

as shown in kern/19564, there is a problem when running two applications
accessing wscons.  After analyzing it (thanks, martin), I see that wsmoused
uses /dev/wsmouse (through the wsmux) and wsconsctl uses wsmouse0.  The
problem is here: one does not know about the other, so when wsconsctl
finishes, it resets mouse data and wsmoused does not receive any more events.
(The PR shows a kernel crash which doesn't happen any more, but wsmoused
stops working... and I guess that kernel state is inconsistent).
If both programs use the same device (wsmouse0), then there is no problem.

To fix this, I've added a counter to control how many times the device has
been opened/closed (note that it can only be opened for read once, but
multiple times for write).  This way, it doesn't matter if it's open through
wsmux or directly.

The same problem applies to wskbd, if I'm right.  So here is the patch:

Index: wskbd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.67
diff -u -u -r1.67 wskbd.c
--- wskbd.c	2003/01/01 00:10:27	1.67
+++ wskbd.c	2003/05/04 11:50:55
@@ -174,6 +174,7 @@
 
 	int		sc_refcnt;
 	u_char		sc_dying;	/* device is being detached */
+	int		sc_opencnt;
 };
 
 #define MOD_SHIFT_L		(1 << 0)
@@ -711,6 +712,8 @@
 	if (sc->sc_base.me_evp != NULL)
 		return (EBUSY);
 
+	sc->sc_opencnt++;
+
 	return (wskbd_do_open(sc, evp));
 }
 #endif
@@ -735,6 +738,8 @@
 	if (sc->sc_dying)
 		return (EIO);
 
+	sc->sc_opencnt++;
+
 	if ((flags & (FREAD | FWRITE)) == FWRITE)
 		/* Not opening for read, only ioctl is available. */
 		return (0);
@@ -784,6 +789,9 @@
 		/* not open for read */
 		return (0);
 
+	if (--sc->sc_opencnt > 0)
+		return (0);
+
 	sc->sc_base.me_evp = NULL;
 	sc->sc_translating = 1;
 	(void)wskbd_enable(sc, 0);
@@ -797,6 +805,9 @@
 wskbd_mux_close(struct wsevsrc *me)
 {
 	struct wskbd_softc *sc = (struct wskbd_softc *)me;
+
+	if (--sc->sc_opencnt > 0)
+		return (0);
 
 	sc->sc_base.me_evp = NULL;
 	sc->sc_translating = 1;
Index: wsmouse.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.29
diff -u -u -r1.29 wsmouse.c
--- wsmouse.c	2003/01/01 00:10:27	1.29
+++ wsmouse.c	2003/05/04 11:50:57
@@ -133,6 +133,7 @@
 
 	int		sc_refcnt;
 	u_char		sc_dying;	/* device is being detached */
+	int		sc_opencnt;
 };
 
 static int  wsmouse_match(struct device *, struct cfdata *, void *);
@@ -467,6 +468,8 @@
 	if (sc->sc_dying)
 		return (EIO);
 
+	sc->sc_opencnt++;
+
 	if ((flags & (FREAD | FWRITE)) == FWRITE)
 		return (0);			/* always allow open for write
 						   so ioctl() is possible. */
@@ -499,6 +502,10 @@
 	if (evar == NULL)
 		/* not open for read */
 		return (0);
+
+	if (--sc->sc_opencnt > 0)
+		return (0);
+
 	sc->sc_base.me_evp = NULL;
 	(*sc->sc_accessops->disable)(sc->sc_accesscookie);
 	wsevent_fini(evar);
@@ -633,6 +640,8 @@
 	if (sc->sc_base.me_evp != NULL)
 		return (EBUSY);
 
+	sc->sc_opencnt++;
+
 	return wsmousedoopen(sc, evp);
 }
 
@@ -640,6 +649,9 @@
 wsmouse_mux_close(struct wsevsrc *me)
 {
 	struct wsmouse_softc *sc = (struct wsmouse_softc *)me;
+
+	if (--sc->sc_opencnt > 0)
+		return (0);
 
 	sc->sc_base.me_evp = NULL;
 	(*sc->sc_accessops->disable)(sc->sc_accesscookie);

Is this ok?

Thanks.

-- 
Julio M. Merino Vidal <jmmv@menta.net>
The NetBSD Project - http://www.NetBSD.org/