I've done some more debugging.  I've not had success in getting a debug
kernel built that will boot my system (Ubuntu) yet, and I don't know why
_that_ is a problem, but it takes ~4 hours per attempt (compiling Linux
is _slow_ on this Via 1GHz system), so I took a different tack.

I started using the ioctls directly, and specifically the USBDEVFS_BULK
ioctl.  I _think_ the Linux framework is dropping bulk-in packets.  More
below:

This is for a mass storage device.

The results I'm seeing look like:

Bulk-Write 31 bytes (CBW)
    dCBWDataTransferLength = 36
    bmCBWFlags = 0x80 (transfer from device to host)
    bCBWLUN = 0
    bCBWCBLength = 06
    CBWCB = 21 data bytes

Bulk-Read, requested 36 data bytes (expected SCSI data), did not arrive

instead

Bulk-Read, got 13 data bytes (instead of 36), corresponding to CSW
    - all values other than dCSWSignature are 0

So instead of getting my 36 byte data packet, followed by the 13 byte
CSW, I instead just get the 13 byte CSW. 

I _think_ that the first 36 byte bulk-in packet is getting
dropped/overwritten by the second bulk-in packet.   Is this normal,
expected behavior?  Do I need to just spawn a reaper thread that hangs
around picking up bulk-in packets and puts them in a userland queue?  I
had heretofore assumed that I could just do the bulk ioctls (I've seen
similar behavior using libusb, which uses submiturb and reapurbndelay)
and pick up the data when I'm ready for it.  Am I misunderstanding
something?

Any advice would be most gratefully received.

Thanks.

    -- Garrett


Alan Stern wrote:
> On Thu, 7 Dec 2006, Garrett D'Amore wrote:
>
>   
>> I'm developing a USB "transport protocol" (for a thin-client
>> application, that basically allows a remote server to access the USB bus
>> on a thin-client device, e.g. so you can access your USB thumbdrive
>> using your thin-client.)  We have this working already for other
>> platforms, so the protocol is "known good".
>>
>> However, I'm having trouble with an implementation built on top of
>> libusb and Linux (specifically, I am using Edgy Eft, kernel
>> 2.6.17-10-386 and libusb-0.1.)
>>
>> What it appears is that doing a usb_bulk_read() on a USB CF reader can
>> "hang" if a zero time out is given, or terminate early if a real timeout
>> is given.
>>     
>
> If you give a zero timeout then you're saying you want to wait until the 
> transfer completes, no matter how long that takes.  If the transfer never 
> completes, then your program would appear to hang.
>
> As for terminating early when a real timeout is given...  Do you really 
> mean "terminate early" (earlier than what -- the timeout expiration?)?  Or 
> do you mean "time out"?
>
> In general, if a USB read transfer fails to complete it is because the 
> device hasn't sent any data, or hasn't indicated that it is finished 
> sending data.
>
>   
>>  This is the first USB bulk read ever issued against the
>> device.  Subsequent reads seem to work okay.  (Note that the device
>> using the exact same operations with a different OS -- proprietary
>> microkernel -- combination doesn't seem to suffer this problem.  So I
>> don't think the device is at fault here.)
>>
>> It looks like the logic in libusb's bulk_read() routine that uses
>> IOCTL_USB_REAPURBNDELAY is deficient somehow -- it looks like it never
>> completes.
>>
>> For the record, here's the code snippet that creates this problem:
>>
>>     rv = usb_bulk_read(ifp->i_handle, endp->e_addr, data, cmd->val, 0);
>>
>> The ep addressed is 0x82, the data length is 36 bytes (cmd->val), and
>> the 0 timeout should wait indefinitely for for this to complete.
>>
>> This is, btw, in a heavily threaded application, although at this point
>> only one thread is ever using the handle represented by ifp->i_handle. 
>> I have used the handle (which is bound to the interface properly with
>> usb_claim_interface, etc.) for other operations, and as indicated,
>> retrying this operation seems to succeed (assuming I use a non-zero
>> value for the timeout.)  I am not happy with that solution though, as
>> I'm not entirely confident that the read is idempotent.
>>
>> A little other info that might be relevant:  here is the relevant entry
>> from the /proc/bus/usb/devices file:
>>
>> T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 13 Spd=12  MxCh= 0
>> D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=16 #Cfgs=  1
>> P:  Vendor=04e6 ProdID=0325 Rev= 5.07
>> S:  Manufacturer=SCM Microsystems Inc.
>> S:  Product=eUSB ORCA Quad Reader
>> S:  SerialNumber=000000000A08
>> C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
>> I:  If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
>> E:  Ad=01(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
>> E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
>>
>>
>> As you can tell, no driver is bound.  My application detects anything
>> that isn't bound to the usbhid, usbhub, or usbfs drivers, and unbinds
>> the kernel driver using the non-portable Linux API.
>>
>> The operation that completes before the read stalls is a USB write of 31
>> bytes.  It appears to me that this is the embedded SCSI commands in the
>> Bulk-Only protocol.
>>     
>
> Be careful when you use the word "stalls".  It has a technical meaning in 
> USB (the device sends a STALL token).  Is that what you mean?  Or do you 
> mean that the read hangs, i.e., fails to complete?
>
>   
>> Any advice for anything else I can do to eliminate this hang/stall
>> condition would be greatly appreciated.  (Is this is a sign that the
>> actual device has stalled?  I wouldn't think so, but I don't know how
>> the Linux USB stack provides a stall to libusb code.)
>>
>> Am I wasting my time with the older libusb-0.1?  Should I port my
>> application to the beta 1.0 stack and try again?
>>
>> Thanks for any advice!
>>     
>
> Try using the usbmon facility (instructions in the kernel source file 
> Documentation/usb/usbmon.txt) to see what is really happening.
>
> Alan Stern
>   


-- 
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134  Fax: 951 325-2191


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to