Re: usbtest and gadget zero with PLX 3380

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux