[Nut-upsuser] lost USB comms under FreeBSD

Daniel O'Connor doconnor at gsoft.com.au
Thu Aug 23 05:07:48 UTC 2007

On Thu, 23 Aug 2007, Charles Lepple wrote:
> On 8/22/07, Daniel O'Connor <doconnor at gsoft.com.au> wrote:
> > On Wed, 22 Aug 2007, Charles Lepple wrote:
> > > NUT drivers poll the UPS every so often, which works fine on
> > > systems where a single libusb call results in a single USB
> > > transaction. In FreeBSD (and probably other BSD systems as well),
> > > interrupt transfers are scheduled periodically, even if the
> > > calling program is not requesting interrupt transfers at the same
> > > rate.
> >
> > I had a look through the USB code and it seems that ugen uses the
> > default value which means that it obtains the value from the end
> > point descriptor.
> Right. IIRC, Linux and Windows only poll the device as often as the
> userspace program or kernel driver request an interrupt transfer.

So does the USB device not have a problem with the endpoint not being 
serviced for a time? (Apparently not :)

In any case it shouldn't matter IMO - if the kernel buffer is full it 
should make no difference it should just mean that the endpoint goes 
unread for a little while and when userland catches up the kernel 
starts reading again.

Perhaps the kernel wrongly marks the interface as 
broken/stalled/whatever when its buffer fills up, or it reads a partial 
message and fills the buffer - that would mean subsequent reads are 
being confused..

Looking at the way ugenintr does it I think the second one is certainly 
possible.. I don't really know much about clists though so I am not 
sure if it's possible to tell how much free space is available in one 
(so you could discard the whole packet if there is not enough room to 
hold it all)

The attached patch will log when this happens and remove data from the 
end of the packet.. Ideally I'd check for the amount of free space 
before putting stuff there but I don't know how to do that :)

Would someone be able to test it? I don't have a USB UPS here at the 
moment, it requires patching your kernel and reloading ugen.ko (at 
least, probably need to reboot if it's in your kernel)

Note that the diff is against HEAD but should be easy to apply manually.

> Probably the best thing would be to have the kernel driver only
> commit to the buffer in multiples of the interrupt transfer size. The
> OMNIVS1000 sends 8-byte packets over the interrupt IN pipe, and stuff
> would occasionally get misaligned by 4 bytes (in a test program that
> repeatedly read 8 bytes from the interrupt endpoint via libusb).

Ahah, I just read this after writing the above :)

Daniel O'Connor software and network engineer
for Genesis Software - http://www.gsoft.com.au
"The nice thing about standards is that there
are so many of them to choose from."
  -- Andrew Tanenbaum
GPG Fingerprint - 5596 B766 97C0 0E94 4347 295E E593 DC20 7B3F CE8C
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ugen-debug.diff
Type: text/x-diff
Size: 841 bytes
Desc: not available
Url : http://lists.alioth.debian.org/pipermail/nut-upsuser/attachments/20070823/e809cd02/attachment.diff 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: This is a digitally signed message part.
Url : http://lists.alioth.debian.org/pipermail/nut-upsuser/attachments/20070823/e809cd02/attachment.pgp 

More information about the Nut-upsuser mailing list