[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.

allan

>
>

-- 
"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