usb/110855: ugen: interrupt in msgs are truncated when buffer is full

Hans Petter Selasky hselasky at c2i.net
Tue Mar 27 19:34:01 UTC 2007


On Tuesday 27 March 2007 18:55, Markus Henschel wrote:
> Hans Petter Selasky schrieb:
> > On Tuesday 27 March 2007 11:30, Markus Henschel wrote:
> >> Hans Petter Selasky schrieb:
> >>> On Monday 26 March 2007 16:13, Markus Henschel wrote:
> >>>>> Number:         110855
> >>>>> Category:       usb
> >>>>> Synopsis:       ugen: interrupt in msgs are truncated when buffer is
> >>>>> full Confidential:   no
> >>>>> Severity:       serious
> >>>>> Priority:       medium
> >>>>> Responsible:    freebsd-usb
> >>>>> State:          open
> >>>>> Quarter:
> >>>>> Keywords:
> >>>>> Date-Required:
> >>>>> Class:          change-request
> >>>>> Submitter-Id:   current-users
> >>>>> Arrival-Date:   Mon Mar 26 14:20:04 GMT 2007
> >>>>> Closed-Date:
> >>>>> Last-Modified:
> >>>>> Originator:     Markus Henschel
> >>>>> Release:        6.2 custom kernel
> >>>>> Organization:
> >>>>
> >>>> Bally Wulff Automaten GmbH
> >>>>
> >>>>> Environment:
> >>>>
> >>>> FreeBSD freebsd-1.bally.de 6.2-RELEASE FreeBSD 6.2-RELEASE #11: Fri
> >>>> Mar 23 21:28:38 CET 2007
> >>>> prog at freebsd-1.bally.de:/usr/obj/usr/src/sys/BALLYWULFF  i386
> >>>>
> >>>>> Description:
> >>>>
> >>>> We use ugen for some user space drivers. When an interrupt in endpoint
> >>>> is used ugen creates a queue that is filled by the kernel. The user
> >>>> space driver is responsible for reading data from the device file. If
> >>>> this happens too slow the queue is full and new msgs arriving from the
> >>>> usb device are lost. This behavior is OK.
> >>>>
> >>>> The problem is that the queue is not a multiple of the interrupt in
> >>>> endpoints msgs size. So it is possible that the last msg in the queue
> >>>> is truncated. This is very hard to detect for a user space driver. The
> >>>> data stream seen by the user space driver will contain an incomplete
> >>>> msgs directly followed by the next message without knowing truncation
> >>>> happened (except when using some data corruption detection mechanism).
> >>>>
> >>>> It would be much better if ugen would fill the queues of interrupt in
> >>>> endpoints until there is no more space for a complete msg. This way
> >>>> the user space driver will not loose sync with the incoming msgs.
> >>>
> >>> The new USB stack has this fixed already. What I do is that the USB
> >>> driver stops polling the interrupt endpoint when the user-land
> >>> application does not read data. When the user-land application has read
> >>> a packet, the interrupt endpoint is started again. The only problem is
> >>> that some devices, like a Microsoft mouse I have, stops working
> >>> immediately when its internal buffer overflows. Bad hardware design.
> >>> But if your hardware is not like that, the new ugen, which is part of
> >>> the new USB driver, will work great for you.
> >>>
> >>> Also packet alignment is kept between reads: Only one packet per read.
> >>>
> >>> See:
> >>>
> >>> http://www.turbocat.net/~hselasky/usb4bsd
> >>>
> >>> --HPS
> >>
> >> Thanks,
> >>
> >> I gave it a try and it seems to work fine :-). Could you please explain
> >> how reading an interrupt in endpoint works internally with the new ugen?
> >> Is there still a buffer that recieves data from the endpoint or is each
> >> read request from user land synchronously triggering a read data request
> >> on the interrupt endpoint?
> >
> > Yes, there is a buffer, but the buffer is packet-based, and not a "ring"
> > based, so you will never get problem with packet alignment.
> >
> >> Why isn't O_NONBLOCK working anymore?
> >
> > It is implemented, and it should work. Can you explain more what is not
> > working?
> >
> > --HPS
>
> With the old ugen I did something like:
>
> int iDevice=open("/dev/ugen0.4", O_RDONLY);
> fcntl(iDevice, F_SETFL, O_NONBLOCK);

I've just committed a patch for that to the P4 tree. It will be in SVN in not 
too long. It was just the matter of a missing IOCTL that F_SETFL uses. 
Usually the following works when you want to set/clear non-blocking mode:

int t = 1;
fcntl(iDevice, FIONBIO, &t)

>
> Now the fcntl call fails. But instead this works and does the same:
>
> int iDevice=open("/dev/ugen0.4", O_RDONLY|O_NONBLOCK);
>
>
> I thought the O_NONBLOCK flag was just for the open call itself?!?
> Whatever, it does what I need :-)
>
> The only thing that keeps me from using the new usb stack is umass now.
> When inserting an usb flash memory stick it is detected and says umass
> attached to ii but then it takes ages (more that 30s) for the device
> files to become available. A "camcontrol rescan all" hangs during this
> time too.Is it possible to use the old umass with the new stack or just
> revert umass to an older version from you like 1.6.1?

If you use the SVN version, reverting won't help much. Could you turn on 
debugging: sysctl hw.usb.umass.debug=-1

And see what is going on when you plug your umass device.

>
> BTW: The performance of the new usb stack is great. umass throughput
> with the memory stick nearly increased by 50%!!

Cool.

--HPS


More information about the freebsd-usb mailing list