Subject: Re: wsmux vs wsmouse open problems
To: None <tech-kern@netbsd.org>
From: Julio Merino <jmmv@menta.net>
List: tech-kern
Date: 05/04/2003 18:53:31
Err... just noticed this is wrong.  Forget it.  But the problem stays there.



On Sun, 4 May 2003 14:08:19 +0200
Julio Merino <jmmv@menta.net> wrote:

> 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/


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