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