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.

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.

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.  One of the USB Mass Storage
specification documents explicitly states that under certain circumstances
the host will attempt to read bulk-in data, and if it receives a STALL it
will clear the HALT feature and try again.  Since the gadget has no way to
know when the halt is cleared, it must queue its data while the endpoint
is still halted.  I suppose a workaround would be to add some sort of
asynchronous notification for when the host clears the halt.  But one way 
or another, this is necessary.

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
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.

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.)

Maybe you could substitute a genuine halt for this "conditional halt".  
That would require the gadget to clear the halt by itself without host 
intervention -- but only if the host didn't try to transmit excess data 
and thereby provoke a STALL response, which the gadget has no way of 
knowing!

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

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