[sane-devel] libusb - problems with open/close of device in backend?

m. allan noah anoah@pfeiffer.edu
Tue, 24 May 2005 11:08:10 -0400 (EDT)

On Tue, 24 May 2005, stef wrote:

> On Tue, May 24, 2005 at 01:18:59PM +0200, stef wrote:
>> On Mon, May 23, 2005 at 02:52:27PM -0400, m. allan noah wrote:
>>> steven, i see this exact problem with certain fujitsu scanners. the
>>> difficulty is that USB uses a 0/1 toggling bit during the data transmit
>>> phase. when libusb closes the device, the device should reset the toggle
>>> back to 0, the kernel does. subsequent transmissions should start with
>>> toggle set to 0, but if device thinks it should be 1, then device ignores
>>> packets. windows never closes the device (the driver loads at bootup) so
>>> the fujitsu engineers had no idea what i was talking about (though i note
>>> that later usb2.0 fujitsu scanners do not have this problem)
>>> you have three options that i see:
>>> 1. count the number of data packets you
>>> are sending to scanner, and always send an even number. remember that just
>>> cause you sent or read 16 k of data, does not matter, it was busted up by
>>> lower layers. you need this larger number of smaller packets.
>>> 2. get kernel/libusb to keep current toggle instead of trashing it.
>>> 3. call usb_reset(device) as the very last step before you exit. this will
>>> cause the device to re-enumerate, and reset all of its internal data.
>>> while ugly, this works for me everytime. there are other functions like
>>> usb_clearhalt and usb_resetep, but those dont seem to fix my problem.
>>> my advice? write a little prog that uses libusb directly, and try to do
>>> simple things outside the confines of sane.
>>> allan
>> 	Hello,
>> 	this is really interesting.  I had an intermittent hangup with the
>> genesys backend, depending of tha amount of scan data. I just couldn't
>> figured out why. Now, with your explanation, it does make sense.
>> Dependending on the number of bulk reads, the toggle wasn't set like it
>> should. So I did like you suggest: call usb_reset(device) before closing the
>> device in sane_close(). That got rid of the hang (at least on HP2300C, need
>> to double check for MD6471).
>> 	Now my question is : would it be OK to do it in a backend ? Is there
>> any drawback ?
>> Regards,
>> 	Stef
>> --
> 	OK,
> 	after some tests I can confirm that genesys hangs are related to the
> 'toggle' and that usb_reset() fix this. But unfortunately, resetting affects
> all devices plugged in the usb ports: if I plug 2 scanners on the same pair
> of USB ports, launch 2 xsane, then leave on -> bus is reset, and the left
> xsane can't work since it's device has also been reset.
> 	Well, I guess it's time to count data packets ....
> Regards,
> 	Stef

odd, i have not seen my system reset the entire bus, but maybe i was not 
watching closely enough.

under kernel 2.6, the device should keep the same ids, but under 2.4, the 
id will change. this can be a problem if you dont re-scan the bus after 
the reset.

did you try the other libusb functions like resetep and clearhalt? may 
work for you.



"so don't tell us it can't be done, putting down what you don't know.
money isn't our god, integrity will free our souls" - Max Cavalera