svn commit: r246397 - head/sys/dev/syscons

Ian Lepore ian at FreeBSD.org
Wed Feb 6 15:36:16 UTC 2013


On Wed, 2013-02-06 at 11:16 +0000, Hans Petter Selasky wrote:
> Author: hselasky
> Date: Wed Feb  6 11:16:18 2013
> New Revision: 246397
> URL: http://svnweb.freebsd.org/changeset/base/246397
> 
> Log:
>   Make sure that all mouse buttons are released when clients
>   using /dev/consolectl close. This fixes a problem where if
>   a USB mouse is detached while a button is pressed, that
>   button is never released.
>   
>   MFC after:	1 week
> 
> Modified:
>   head/sys/dev/syscons/syscons.c
> 
> Modified: head/sys/dev/syscons/syscons.c
> ==============================================================================
> --- head/sys/dev/syscons/syscons.c	Wed Feb  6 11:10:41 2013	(r246396)
> +++ head/sys/dev/syscons/syscons.c	Wed Feb  6 11:16:18 2013	(r246397)
> @@ -253,11 +253,13 @@ static struct ttydevsw sc_ttydevsw = {
>  };
>  
>  static d_ioctl_t	consolectl_ioctl;
> +static d_close_t	consolectl_close;
>  
>  static struct cdevsw consolectl_devsw = {
>  	.d_version	= D_VERSION,
> -	.d_flags	= D_NEEDGIANT,
> +	.d_flags	= D_NEEDGIANT | D_TRACKCLOSE,
>  	.d_ioctl	= consolectl_ioctl,
> +	.d_close	= consolectl_close,
>  	.d_name		= "consolectl",
>  };
>  
> @@ -1561,6 +1563,23 @@ consolectl_ioctl(struct cdev *dev, u_lon
>  	return sctty_ioctl(dev->si_drv1, cmd, data, td);
>  }
>  
> +static int
> +consolectl_close(struct cdev *dev, int flags, int mode, struct thread *td)
> +{
> +#ifndef SC_NO_SYSMOUSE
> +	mouse_info_t info;
> +	memset(&info, 0, sizeof(info));
> +	info.operation = MOUSE_ACTION;
> +
> +	/*
> +	 * Make sure all buttons are released when moused and other
> +	 * console daemons exit, so that no buttons are left pressed.
> +	 */
> +	(void) sctty_ioctl(dev->si_drv1, CONS_MOUSECTL, (caddr_t)&info, td);
> +#endif
> +	return (0);
> +}
> +
>  static void
>  sc_cnprobe(struct consdev *cp)
>  {

I think the D_TRACKCLOSE flag is not what you want here.  Based on my
(admittedly still vague) understanding of it, that flag is almost never
the right thing for a driver to use.

If you need that action to be taken when the last open instance of the
driver is closed, that's what you get without D_TRACKCLOSE.  If you need
it to be called as many times as the open routine was called... well,
that's the the confusing thing.  It's not clear to me that there's any
way to get that effect, but the cdevpriv destructor may be the closest
thing available.

I think the essential problem is that open and close are not strictly
paired.  For example, a forked child inherits open descriptors without
open() calls happening, and revoke() is a way to destroy references
without a close() call.  But the details of all this are murky to me,
and the most-enlightening mailing list posts you can find on it are full
of phrases like "vref counters for devfs nodes" and "vnode is reclaimed"
that make the discussion difficult to follow if you're not intimate with
the internals of the vm system.

-- Ian




More information about the svn-src-all mailing list