Skip to content
  • Elson Roy Serrao's avatar
    usb: dwc3: Properly handle delayed status in ep_halt context · 972f8a7b
    Elson Roy Serrao authored
    
    
    There are two ways of clearing the halt condition.
    
    (1) host initiated through control transfer CLEAR_FEATURE(endpoint)
    (2) device requesting UDC to clear the halt endpoint.
    
    In (1), we stop the active transfer and wait for it before sending the
    status response for the control transfer. So it involves delayed_response
    i.e USB_GADGET_DELAYED_STATUS. In (2) there is no delayed response involved
    since it is not a control transfer. However the current code does not
    distinguish the part of handling delayed response upon ENDPONT command
    completion. In both cases, we try to send the delayed response. This can
    result into unexpected behavior when the delayed status is imposed for a
    different reason which gets cleared by the case (2) like explained in
    the below scenario.
    
    1. Vendor specific control transfer returns USB_GADGET_DELAYED_STATUS.
    2. DWC3 gadget sets dwc->delayed_status to '1'.
    3. Another function driver issues a usb_ep_clear_halt() call.
    4. DWC3 gadget issues dwc3_stop_active_transfer() and sets
       DWC3_EP_PENDING_CLEAR_STALL.
    5. EP command complete interrupt triggers for the end transfer, and
       dwc3_ep0_send_delayed_status() is allowed to run, as delayed_status
       is '1' due to step#1.
    6. STATUS phase is sent, and delayed_status is cleared.
    7. Vendor specific control transfer is finished being handled, and issues
       usb_composite_setup_continue().  This results in queuing of a data
       phase.
    
    The dwc3_gadget_ep_set_halt() API invoked by the two cases above is
    distinguished by the protocol flag. Cache this protocol flag so that
    DWC3 gadget is aware of when the clear halt is due to a SETUP request
    from the host versus when it is sourced from a function driver. This
    allows for the EP command complete interrupt to know if it needs to
    issue a delayed status phase.
    
    Change-Id: I3b07bbda674103191a793319e3e2e09059eb2a25
    Signed-off-by: default avatarElson Roy Serrao <quic_eserrao@quicinc.com>
    972f8a7b