On Wed, 7 May 2014, Zhuang Jin Can wrote:

> A delayed status request may be queued before composite framework returns
> USB_GADGET_DELAYED_STATUS, because the thread queueing the request can run
> on a different core in parallel with the control request irq.
> 
> SETUP XferComplete IRQ                        fsg_main_thread
> ----------------------                        ---------------
>       |                                       |
> spin_lock_irqsave(&dwc->lock)               sleeping
>       |                                       |
>       ...                                     ...
> dwc3_ep0_inspect_setup()                      |
>       |                                       |
> dwc3_ep0_delegate_req()                       |
>       |                                       |
>       ...                                     |
> spin_unlock(&dwc->lock);                      |
>       |                                       |
> fsg_set_alt()   ======> Signal Wakeup ====>   |
>       |                                       |
> other gadgets->set_alt()             handle exception
>       |                                       |
>       |                       usb_composite_setup_continue()
>       |                                       |
>       |                       spin_lock_irqsave(&dwc->lock)
>       |                            __dwc3_gadget_ep0_queue()
>       |                                delay_status is false
>       |                       spin_unlock_irqrestore(&dwc->lock)
>       |                                       |
>       |                                    sleeping
> spin_lock(&dwc->lock);                                |
>       |                                       |
> delayed_status=true                           |
>       |                                       |
> 
>               STATUS XferNotReady IRQ
>               ------------------------
>                       |
>               dwc3_ep0_xfernotready()
>                       |
>                  delayed_status is true, return;
> 
> The result is the status packet will never be transferred, and
> delayed_status is not cleared.
> 
> Signed-off-by: Zhuang Jin Can <jin.can.zhu...@intel.com>
> Reported-by: Zhou Liping <liping.z...@intel.com>

A similar problem can occur in the opposite sense: The thread queuing
the delayed status request might be delayed for so long that another
SETUP packet arrives from the host first.  In that case, the delayed
status request is a response for a stale transfer, so it must not be
sent to the host.

Do dwc3 and composite.c handle this case correctly?

Back in the old g_file_storage driver, I addressed this issue by
keeping a counter of all the setup requests.  When it came time to send
a delayed status response, the response would be sent only if the
counter had not changed from when the original setup request was
received.

As far as I can see, composite.c doesn't do anything like that.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to