On Tue, 24 Apr 2012, Felipe Balbi wrote: > > Why is this a problem? All that should happen is you transfer less > > data than g_zero expects. Either way, the transfer should succeed. > > ok, let's say usbtest is sending at 1024 byte chunks 5 times and g_zero > uses a 4096 byte buffer, this will mean UDC will start a 4k e.g. DMA > transfer and that single DMA transfer will receive the first 4 chunks > sent by usbtest. > > Now g_zero blindly starts another 4k transfer, UDC's DMA is kicked, but > host only sends 1k. That transfer will never finish because 1024 is > aligned to wMaxPacketSize (so, not a short packet) and is not the end of > the transfer kicked to DMA (which was 4k). Yes, that's right. > How do you make this work ? It seems to me that what you described _does_ work. usbtest transfers all the data it wants and gets back the appropriate ACKs. Where's the problem? Sure, the UDC ends up sitting in the middle of an unfinished OUT transfer. So what? There's nothing wrong with that. > If you look at most UDC's code, you will see there's a DMA abort or some > sort of transfer abort mechanism whenever actual == length, It's not an abort mechanism; it's a completion mechanism. This is true of _every_ DMA transfer everywhere, not just in UDCs -- there always is a transfer length, and the transfer stops when that many bytes have been sent/received. If anything, USB's odd ingredient is the "stop early upon receiving a short packet" mechanism. > this is what > makes it magically work, but IMHO, that's not how USB is supposed to be > implemented. Look at all other classes, they have a way to negotiate > size of transfer (Mass Storage's CBW, Ethernet's MTU, MTP's handling of > ZLP and so on) so there will always be a way to finish the transfer. But > g_zero is special, because it relies on the UDC aborting a transfer > which was bigger than necessary. The incomplete transfer doesn't need to be aborted. It can remain in its incomplete state and still be useful. For example, let's say that the user runs the same test over again, with the same parameters. This time, when usbtest sends the first three 1024-byte chunks, g_zero's transfer will complete. g_zero blindly goes ahead and queues another request. The last two 1024-byte chunks from usbtest will partially fill the buffer and then the test will end, again successfully. In short, nothing's wrong! Now it's true that under some circumstances the incomplete transfer will need to be aborted. For example, if the host sends a Set-Config or Set-Interface request, the existing endpoints will be disabled and then possibly new endpoints will be enabled. But UDC drivers have to be able to cope with that sort of thing anyway. If you insist on thinking about this in terms of class definitions then think of g_zero as implementing a special class which specifies that transfers do not have pre-arranged lengths. They can terminate when a short packet is received, or they can continue indefinitely, until the configuration or altsetting is changed, or until the device is unplugged from the host. For g_zero this makes sense, because the data being transferred does not carry any meaning: Data going to the device is thrown away, and data coming from the device is always zero (or whatever preset pattern g_zero uses). Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html