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/