Loading drivers/usb/dwc3/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ struct dwc3_hwparams { * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @start_config_issued: true when StartConfig command has been issued * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state Loading Loading @@ -633,6 +634,7 @@ struct dwc3 { unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned start_config_issued:1; unsigned setup_packet_pending:1; unsigned delayed_status:1; enum dwc3_ep0_next ep0_next_event; Loading drivers/usb/dwc3/ep0.c +3 −0 Original line number Diff line number Diff line Loading @@ -625,6 +625,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; dep->flags &= ~DWC3_EP_BUSY; dwc->setup_packet_pending = false; switch (dwc->ep0state) { case EP0_SETUP_PHASE: Loading Loading @@ -726,6 +727,8 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { dwc->setup_packet_pending = true; /* * This part is very tricky: If we has just handled * XferNotReady(Setup) and we're now expecting a Loading drivers/usb/dwc3/gadget.c +32 −0 Original line number Diff line number Diff line Loading @@ -1640,6 +1640,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->start_config_issued = false; dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->setup_packet_pending = false; } static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) Loading Loading @@ -1676,6 +1677,37 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s\n", __func__); /* * WORKAROUND: DWC3 revisions <1.88a have an issue which * would cause a missing Disconnect Event if there's a * pending Setup Packet in the FIFO. * * There's no suggested workaround on the official Bug * report, which states that "unless the driver/application * is doing any special handling of a disconnect event, * there is no functional issue". * * Unfortunately, it turns out that we _do_ some special * handling of a disconnect event, namely complete all * pending transfers, notify gadget driver of the * disconnection, and so on. * * Our suggested workaround is to follow the Disconnect * Event steps here, instead, based on a setup_packet_pending * flag. Such flag gets set whenever we have a XferNotReady * event on EP0 and gets cleared on XferComplete for the * same endpoint. * * Refers to: * * STAR#9000466709: RTL: Device : Disconnect event not * generated if setup packet pending in FIFO */ if (dwc->revision < DWC3_REVISION_188A) { if (dwc->setup_packet_pending) dwc3_gadget_disconnect_interrupt(dwc); } /* Enable PHYs */ dwc3_gadget_usb2_phy_power(dwc, true); dwc3_gadget_usb3_phy_power(dwc, true); Loading Loading
drivers/usb/dwc3/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ struct dwc3_hwparams { * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @start_config_issued: true when StartConfig command has been issued * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state Loading Loading @@ -633,6 +634,7 @@ struct dwc3 { unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned start_config_issued:1; unsigned setup_packet_pending:1; unsigned delayed_status:1; enum dwc3_ep0_next ep0_next_event; Loading
drivers/usb/dwc3/ep0.c +3 −0 Original line number Diff line number Diff line Loading @@ -625,6 +625,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; dep->flags &= ~DWC3_EP_BUSY; dwc->setup_packet_pending = false; switch (dwc->ep0state) { case EP0_SETUP_PHASE: Loading Loading @@ -726,6 +727,8 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { dwc->setup_packet_pending = true; /* * This part is very tricky: If we has just handled * XferNotReady(Setup) and we're now expecting a Loading
drivers/usb/dwc3/gadget.c +32 −0 Original line number Diff line number Diff line Loading @@ -1640,6 +1640,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->start_config_issued = false; dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->setup_packet_pending = false; } static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) Loading Loading @@ -1676,6 +1677,37 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s\n", __func__); /* * WORKAROUND: DWC3 revisions <1.88a have an issue which * would cause a missing Disconnect Event if there's a * pending Setup Packet in the FIFO. * * There's no suggested workaround on the official Bug * report, which states that "unless the driver/application * is doing any special handling of a disconnect event, * there is no functional issue". * * Unfortunately, it turns out that we _do_ some special * handling of a disconnect event, namely complete all * pending transfers, notify gadget driver of the * disconnection, and so on. * * Our suggested workaround is to follow the Disconnect * Event steps here, instead, based on a setup_packet_pending * flag. Such flag gets set whenever we have a XferNotReady * event on EP0 and gets cleared on XferComplete for the * same endpoint. * * Refers to: * * STAR#9000466709: RTL: Device : Disconnect event not * generated if setup packet pending in FIFO */ if (dwc->revision < DWC3_REVISION_188A) { if (dwc->setup_packet_pending) dwc3_gadget_disconnect_interrupt(dwc); } /* Enable PHYs */ dwc3_gadget_usb2_phy_power(dwc, true); dwc3_gadget_usb3_phy_power(dwc, true); Loading