Subject: kern/33109: USB hid devices should be able to flush input buffers
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: seebs <seebs@vash.cel.plethora.net>
List: netbsd-bugs
Date: 03/20/2006 16:05:00
>Number:         33109
>Category:       kern
>Synopsis:       USB hid devices should be able to flush input buffers
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 20 16:05:00 +0000 2006
>Originator:     seebs
>Release:        NetBSD 3.99.15
>Organization:
	
>Environment:
System: NetBSD vash.cel.plethora.net 3.99.15 NetBSD 3.99.15 (VASH) #1: Tue Jan 3 23:03:30 CST 2006 seebs@vash.cel.plethora.net:/sys/arch/i386/compile/VASH i386
Architecture: i386
Machine: i386
>Description:
	There exists at least one device (a bill reader/stacker) which, rather
	than sending interrupt messages, just queues up messages at
	intervals... Meaning that it's useful to be able to flush the buffer
	of incoming messages sometimes.
>How-To-Repeat:
	Try to develop a driver for a USB bill reader.
>Fix:
	The following trivial patch adds a flush of incoming data from the
	input buffer when trying to set immediate mode on a device.  I am
	pretty sure that it's always desirable to flush the buffer, and it
	is useful on the device in question.

	With this:

                int one = 1;
		ioctl(m->fd, USB_SET_IMMED, &one);

	allows a user application to flush a buffer full of unwanted packets.

Index: uhid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhid.c,v
retrieving revision 1.68
diff -c -r1.68 uhid.c
*** uhid.c	11 Dec 2005 12:24:01 -0000	1.68
--- uhid.c	20 Mar 2006 15:57:55 -0000
***************
*** 470,475 ****
--- 470,476 ----
  
  	case USB_SET_IMMED:
  		if (*(int *)addr) {
+ 			ndflush(&sc->sc_q, 1024);
  			extra = sc->sc_hdev.sc_report_id != 0;
  			err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
  						buffer, sc->sc_isize + extra);