On 01/23/2012 06:22 PM, Alan Stern wrote:
On Mon, 23 Jan 2012, Sebastian Andrzej Siewior wrote:
The following scenario:
- use a third party tool
- issue SetConfiguration, start a transfer
- g_zero enqueues 4k reqs. Be rude and stop after a multiple of maxpacketsize
but before the 4k
- Assume the UDC can handle 4k transfer in one go and will interrupt after the
4k arrived or a short transfer. That the transfer is still "busy".
- now soft the disconnect the device.
- the UDC gets a SetConfiguration 0 and will disable all endpoints
- disabling an endpoint means cancles all pending transfers.
On DWC3 we issue a cancel transfer command and wait for the command/transfer to
complete.
Do you mean you _don't_ wait for the transfer to complete?
yes. Lets say 2k of 4k have been transferred. I don't get an interrupt
which says transfer complete. So I am interrupting the transfer "in
progress."
That means we return immediately from ->disable(). The _gadget_ has to
wait for the ->complete() callback. g_zero does not and the result is:
This patch is wrong; DWC3 must be fixed instead. From
include/linux/usb/gadget.h:
/**
* usb_ep_disable - endpoint is no longer usable
*
* no other task may be using this endpoint when this is called.
* any pending and uncompleted requests will complete with status
* indicating disconnect (-ESHUTDOWN) before this call returns.
*/
Fixing this not easy. We are atomic here and I can't sleep. A busy loop
to wait until the command is not simple (but ugly) because other
commands may complete in between. So the only way to fix this behavior
from dwc3's point of view is allowing usb_ep_disable() to be called in
process context. That means I have to get composite to use a workqueue
as you suggested in other thread for other reason. So it seems now to
be unavoidable.....
Sebastian
Alan Stern
Sebastian
--
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