Alan Stern wrote:
David:

A few things have come while planning my gadget driver.

The gadgetfs API still looks a bit preliminary. Judging by the source,
there doesn't even appear to be any way to halt an endpoint! Anyway, I
decided not to use it; the performance penalties would make it a bad model for this purpose in any case.

Halt endpoints by doing a "wrong direction" I/O ... read from an IN endpoint (instead of writing to the host), or write to an OUT endpoint (instead of reading what it wrote). This idiom avoids use of ioctls, and makes use of a code path that would otherwise just return an error.

It's a bit preliminary mostly in the sense that it's not been widely used
yet, and I want to change how SET_CONFIGURATION gets handled (as I mentioned).
But otherwise it's behaved well enough, except for some of the 2.4 hacks.

Yes, I tend to think that userspace isn't the right place for a mass storage
gadget driver to live.  Even things like automounting usually limit the
userspace hooks to directory lookups, instead of bulk i/o.  On the other
hand there's a lot to be said for drivers that won't oops because they
aren't in the kernel ... :)


The kerneldoc for usb_ep_set_halt() says that the endpoint will remain
halted until the host clears it. Is that really true, the gadget driver
can't clear the HALT feature? The kerneldoc says that usb_ep_clear_halt() should be used when changing altsettings; if it works then, why doesn't it
work at other times? This could use clarification.

Basically it does remain halted until the host clears it ... changing altsettings is done only at host request! :)

But yes, that's worth some clarifying.  The main trouble spot today is
that some hardware (pxa2xx_udc for example) doesn't support it in any case
(and can't use altsettings).


usb_ep_queue() says it will return an error if the endpoint is halted.
This isn't acceptable; we have to be able to queue bulk-in data on a
halted endpoint, at the very least....

You'll be glad to know that's not correct ... none of the drivers even check, since they don't (can't) know if the endpoint is halted. Doc fix is needed.


A related issue has to do with setting the HALT feature when the host
tries to read/write too much.  The premature end of a bulk-in transfer can
be indicated by a short or zero-length packet.  But you recommend avoiding
ZLPs, and if the total transfer length is divisible by the packet size
then there won't be a short packet.  The correct thing to do is to halt
the endpoint when the slave receives an excess IN PID.  But we don't want

The device will be NAKing in such cases, when the host asks for a packet and there's no data. Avoiding ZLPs is mostly a practical matter for protocols, since not all hardware handles them ... if you're working with hardware that handles them, and with a device protocol where the host will read them, by all means write a ZLP to the host. It "ought to work" just fine.

Sending an automagic STALL response to the host would be wrong; the controller
driver can't even know if an IN is "excess" or just "early" (before the
gadget driver had quite finished preparing the data).

Example:  if the host writes READ_10, the gadget driver will read that and
start processing it.  The host will usually try to read the data bytes next,
but the gadget might not be able to write any until a disk delivers the data.
It would be incorrect to STALL ... but it's very correct to NAK.


to halt if there is no excess IN request, because in that case the host
shouldn't have to clear the halt. That means there has to be a way to set
the state of a bulk endpoint so that it responds to the host by halting
but otherwise remains running, a "conditionally halted" state. And of course, the gadget needs to be able to take the endpoint out of this state back to its normal running state.

Again, seems like NAK is the answer. And the way to make the gadget stop NAKing is to provide some data for it to deliver to the host: submit a request to that IN endpoint, with its data buffer.

If a STALL is the right response, then halt the endpoint.  Otherwise the
only non-error responses are to NAK, or to provide the requested DATA.



Similar reasoning applies to OUT transfers. We don't want the controller
to ACK (and store in its FIFO) excess data that the gadget can't accept; we want it to stall. In fact, to avoid races it would be good to add an
extra flag bit to struct usb_request, saying that as soon as the request
finishes normally the endpoint should be placed in this "conditional-halt" state. (For bulk-in requests such a flag isn't necessary because we
aren't racing the hardware, but it would be nice to have.)

This case is a lot harder. The symmetrical answer is that the device NAKs the OUT transfer (or, at high speed, the PING) until you issue a read ... but it seems like the people designing hardware don't often support that flow control model. (Likely because it increases latencies, and isn't actually necessary.)

So hardware is usually set up to accept OUT data whenever the endpoint
is enabled and its FIFO has space.  So if the host managed to find time
to get the data to that "streaming" endpoint, it'll be there when your
gadget driver finds time to process it.

When you're writing a gadget driver this should all be transparent unless
the device protocol is mis-designed.  But you'll need to know that for
both IN and OUT transfers, data might still sit in endpoint FIFOs after
your write (or read, respectively) transfer complete() callback.  Lots
of driver frameworks act in that same way.


I'm sure other things will come up in due course, but for now that's all I can think of.

Thanks again for the feedback, and I look forward to hearing more from you ... :)

- Dave



Alan Stern






-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to