summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/gadget.c
AgeCommit message (Collapse)Author
2022-09-07usb: dwc3: Avoid unmapping USB requests if endxfer is not completeWesley Cheng
If DWC3_EP_DELAYED_STOP is set during stop active transfers, then do not continue attempting to unmap request buffers during dwc3_remove_requests(). This can lead to SMMU faults, as the controller has not stopped the processing of the TRB. Defer this sequence to the EP0 out start, which ensures that there are no pending SETUP transactions before issuing the endxfer. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220901193625.8727-2-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-09-05Merge 6.0-rc4 into usb-nextGreg Kroah-Hartman
We need the USB fixes in here and this resolves the merge issue in: drivers/usb/dwc3/gadget.c Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-31usb: dwc3: gadget: Continue handling EP0 xfercomplete eventsWesley Cheng
During soft disconnect, EP0 events are expected to be handled in order to allow the controller to successfully move into the halted state. Since __dwc3_gadget_stop() is executed before polling, EP0 has been disabled, and events are being blocked. Allow xfercomplete events to be handled, so that cached SETUP packets can be read out from the internal controller memory. Without doing so, it will lead to endxfer timeouts, which results to controller halt failures. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220817182359.13550-5-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-31usb: dwc3: gadget: Synchronize IRQ between soft connect/disconnectWesley Cheng
Ensure that there are no pending events being handled in between soft connect/disconnect transitions. As we are keeping interrupts enabled, and EP0 events are still being serviced, this avoids any stale events from being serviced. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220817182359.13550-4-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-31usb: dwc3: gadget: Force sending delayed status during soft disconnectWesley Cheng
If any function drivers request for a delayed status phase, this leads to a SETUP transfer timeout error, since the function may take longer to process the DATA stage. This eventually results in end transfer timeouts, as there is a pending SETUP transaction. In addition, allow the DWC3_EP_DELAY_STOP to be set for if there is a delayed status requested. Ocasionally, a host may abort the current SETUP transaction, by issuing a subsequent SETUP token. In those situations, it would result in an endxfer timeout as well. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220817182359.13550-3-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-31usb: dwc3: Do not service EP0 and conndone events if soft disconnectedWesley Cheng
There are some operations that need to be ignored if there is a soft disconnect in progress. This is to avoid having a pending EP0 transfer in progress while attempting to stop active transfers and halting the controller. There were several instances seen where a soft disconnect was able to occur during early link negotiation, i.e. bus reset/conndone, which leads to the conndone handler re-configuring EPs while attempting to halt the controller, as DEP flags are cleared as part of the soft disconnect path. ep0out: cmd 'Start New Configuration' ep0out: cmd 'Set Endpoint Transfer Resource' ep0in: cmd 'Set Endpoint Transfer Resource' ep1out: cmd 'Set Endpoint Transfer Resource' ... event (00030601): Suspend [U3] event (00000101): Reset [U0] ep0out: req ffffff87e5c9e100 length 0/0 zsI ==> 0 event (00000201): Connection Done [U0] ep0out: cmd 'Start New Configuration' ep0out: cmd 'Set Endpoint Transfer Resource' In addition, if a soft disconnect occurs, EP0 events are still allowed to process, however, it will stall/restart during the SETUP phase. The host is still able to query for the DATA phase, leading to a xfernotready(DATA) event. Since none of the SETUP transfer parameters are populated, the xfernotready is treated as a "wrong direction" error, leading to a duplicate stall/restart routine. Add the proper softconnect/connected checks in sequences that are potentially involved during soft disconnect processing. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220817182359.13550-2-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-19usb: dwc3: gadget: conditionally remove requestsMichael Grzeschik
The functions stop_active_transfers and ep_disable are both calling remove_requests. This functions in both cases will giveback the requests with status ESHUTDOWN, which also represents an physical disconnection. For ep_disable this is not true. This patch adds the status parameter to remove_requests and sets the status to ECONNRESET on ep_disable. Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220720213523.1055897-1-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-08-18usb: dwc3: gadget: Avoid duplicate requests to enable Run/StopWesley Cheng
Relocate the pullups_connected check until after it is ensured that there are no runtime PM transitions. If another context triggered the DWC3 core's runtime resume, it may have already enabled the Run/Stop. Do not re-run the entire pullup sequence again, as it may issue a core soft reset while Run/Stop is already set. This patch depends on commit 69e131d1ac4e ("usb: dwc3: gadget: Prevent repeat pullup()") Fixes: 77adb8bdf422 ("usb: dwc3: gadget: Allow runtime suspend if UDC unbinded") Cc: stable <stable@kernel.org> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220728020647.9377-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-07-18Merge 5.19-rc7 into usb-nextGreg Kroah-Hartman
We need the USB fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-07-08usb: dwc3: gadget: fix high speed multiplier settingMichael Grzeschik
For High-Speed Transfers the prepare_one_trb function is calculating the multiplier setting for the trb based on the length parameter of the trb currently prepared. This assumption is wrong. For trbs with a sg list, the length of the actual request has to be taken instead. Fixes: 40d829fb2ec6 ("usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets") Cc: stable <stable@kernel.org> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220704141812.1532306-3-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-07-08usb: dwc3: gadget: refactor dwc3_repare_one_trbMichael Grzeschik
The function __dwc3_prepare_one_trb has many parameters. Since it is only used in dwc3_prepare_one_trb there is no point in keeping the function. We merge both functions and get rid of the big list of parameters. Fixes: 40d829fb2ec6 ("usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets") Cc: stable <stable@kernel.org> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220704141812.1532306-2-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-29usb: dwc3: gadget: Fix event pending checkThinh Nguyen
The DWC3_EVENT_PENDING flag is used to protect against invalid call to top-half interrupt handler, which can occur when there's a delay in software detection of the interrupt line deassertion. However, the clearing of this flag was done prior to unmasking the interrupt line, creating opportunity where the top-half handler can come. This breaks the serialization and creates a race between the top-half and bottom-half handler, resulting in losing synchronization between the controller and the driver when processing events. To fix this, make sure the clearing of the DWC3_EVENT_PENDING is done at the end of the bottom-half handler. Fixes: d325a1de49d6 ("usb: dwc3: gadget: Prevent losing events in event cache") Cc: stable@vger.kernel.org Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/8670aaf1cf52e7d1e6df2a827af2d77263b93b75.1656380429.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-29usb: dwc3: gadget: fix a kernel-doc warningMauro Carvalho Chehab
The multiplier parameter of dwc3_gadget_calc_tx_fifo_size() was not documented: drivers/usb/dwc3/gadget.c:675: warning: Function parameter or member 'mult' not described in 'dwc3_gadget_calc_tx_fifo_size' Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org> Link: https://lore.kernel.org/r/bd599a18cea45c57d91c69d3e30d8b1e8ea69dd1.1656409369.git.mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-10usb: dwc3: gadget: Fix IN endpoint max packet size allocationWesley Cheng
The current logic to assign the max packet limit for IN endpoints attempts to take the default HW value and apply the optimal endpoint settings based on it. However, if the default value reports a TxFIFO size large enough for only one max packet, it will divide the value and assign a smaller ep max packet limit. For example, if the default TxFIFO size fits 1024B, current logic will assign 1024/3 = 341B to ep max packet size. If function drivers attempt to request for an endpoint with a wMaxPacketSize of 1024B (SS BULK max packet size) then it will fail, as the gadget is unable to find an endpoint which can fit the requested size. Functionally, if the TxFIFO has enough space to fit one max packet, it will be sufficient, at least when initializing the endpoints. Fixes: d94ea5319813 ("usb: dwc3: gadget: Properly set maxpacket limit") Cc: stable <stable@kernel.org> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220523213948.22142-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-19usb: dwc3: gadget: Move null pinter check to proper placeAlbert Wang
When dwc3_gadget_ep_cleanup_completed_requests() called to dwc3_gadget_giveback() where the dwc3 lock is released, other thread is able to execute. In this situation, usb_ep_disable() gets the chance to clear endpoint descriptor pointer which leds to the null pointer dereference problem. So needs to move the null pointer check to a proper place. Example call stack: Thread#1: dwc3_thread_interrupt() spin_lock -> dwc3_process_event_buf() -> dwc3_process_event_entry() -> dwc3_endpoint_interrupt() -> dwc3_gadget_endpoint_trbs_complete() -> dwc3_gadget_ep_cleanup_completed_requests() ... -> dwc3_giveback() spin_unlock Thread#2 executes Thread#2: configfs_composite_disconnect() -> __composite_disconnect() -> ffs_func_disable() -> ffs_func_set_alt() -> ffs_func_eps_disable() -> usb_ep_disable() wait for dwc3 spin_lock Thread#1 released lock clear endpoint.desc Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception") Cc: stable <stable@kernel.org> Signed-off-by: Albert Wang <albertccwang@google.com> Link: https://lore.kernel.org/r/20220518061315.3359198-1-albertccwang@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-19usb: dwc3: Fix ep0 handling when getting reset while doing control transferMayank Rana
According to the databook ep0 should be in setup phase during reset. If host issues reset between control transfers, ep0 will be in an invalid state. Fix this by issuing stall and restart on ep0 if it is not in setup phase. Also SW needs to complete pending control transfer and setup core for next setup stage as per data book. Hence check ep0 state during reset interrupt handling and make sure active transfers on ep0 out/in endpoint are stopped by queuing ENDXFER command for that endpoint and restart ep0 out again to receive next setup packet. Signed-off-by: Mayank Rana <quic_mrana@quicinc.com> Link: https://lore.kernel.org/r/1651693001-29891-1-git-send-email-quic_mrana@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: gadget: Delay issuing End TransferThinh Nguyen
If the controller hasn't DMA'ed the Setup data from its fifo, it won't process the End Transfer command. Polling for the command completion may block the driver from servicing the Setup phase and cause a timeout. Previously we only check and delay issuing End Transfer in the case of endpoint dequeue. Let's do that for all End Transfer scenarios. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/2fcf3b5d90068d549589a57a27a79f76c6769b04.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: gadget: Only End Transfer for ep0 data phaseThinh Nguyen
The driver shouldn't be able to issue End Transfer to the control endpoint at anytime. Typically we should only do so in error cases such as invalid/unexpected direction of Data Phase as described in the control transfer flow of the programming guide. It _may_ end started data phase during controller deinitialization from soft disconnect or driver removal. However, that should not happen because the driver should be maintained in EP0_SETUP_PHASE during driver tear-down. On soft-connect, the controller should be reset from a soft-reset and there should be no issue starting the control endpoint. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/3c6643678863a26702e4115e9e19d7d94a30d49c.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: ep0: Don't prepare beyond Setup stageThinh Nguyen
Since we can't guarantee that the host won't send new Setup packet before going through the device-initiated disconnect, don't prepare beyond the Setup stage and keep the device in EP0_SETUP_PHASE. This ensures that the device-initated disconnect sequence can go through gracefully. Note that the controller won't service the End Transfer command if it can't DMA out the Setup packet. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/6bacec56ecabb2c6e49a09cedfcac281fdc97de0.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup()Thinh Nguyen
If the GEVNTCOUNT indicates events in the event buffer, the driver needs to acknowledge them before the controller can halt. Simply let the interrupt handler acknowledges the remaining event generated by the controller while polling for DSTS.DEVCTLHLT. This avoids disabling irq and taking care of race condition between the interrupt handlers and pullup(). Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/ea306ec93c41ccafbdb5d16404ff3b6eca299613.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: gadget: Refactor pullup()Thinh Nguyen
Move soft-disconnect sequence out of dwc3_gadget_pullup(). No functional change here. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/4c0f259b17d95acaaa931f90276683a48a32fe22.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-05usb: dwc3: gadget: Prevent repeat pullup()Thinh Nguyen
Don't do soft-disconnect if it's previously done. Likewise, don't do soft-connect if the device is currently connected and running. It would break normal operation. Currently the caller of pullup() (udc's sysfs soft_connect) only checks if it had initiated disconnect to prevent repeating soft-disconnect. It doesn't check for soft-connect. To be safe, let's keep the check here regardless whether the udc core is fixed. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/1c1345bd66c97a9d32f77d63aaadd04b7b037143.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-03Merge 5.18-rc5 into usb-nextGreg Kroah-Hartman
We need the USB fixes in here, and this resolves a merge issue in drivers/usb/dwc3/drd.c Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-26usb: dwc3: gadget: Return proper request statusThinh Nguyen
If the user sets the usb_request's no_interrupt, then there will be no completion event for the request. Currently the driver incorrectly uses the event status of a different request to report the status for a request with no_interrupt. The dwc3 driver needs to check the TRB status associated with the request when reporting its status. Note: this is only applicable to missed_isoc TRB completion status, but the other status are also listed for completeness/documentation. Fixes: 6d8a019614f3 ("usb: dwc3: gadget: check for Missed Isoc from event status") Cc: <stable@vger.kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/db2c80108286cfd108adb05bad52138b78d7c3a7.1650673655.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-23usb: dwc3: gadget: Replace list_for_each_entry_safe() if using givebackWesley Cheng
The list_for_each_entry_safe() macro saves the current item (n) and the item after (n+1), so that n can be safely removed without corrupting the list. However, when traversing the list and removing items using gadget giveback, the DWC3 lock is briefly released, allowing other routines to execute. There is a situation where, while items are being removed from the cancelled_list using dwc3_gadget_ep_cleanup_cancelled_requests(), the pullup disable routine is running in parallel (due to UDC unbind). As the cleanup routine removes n, and the pullup disable removes n+1, once the cleanup retakes the DWC3 lock, it references a request who was already removed/handled. With list debug enabled, this leads to a panic. Ensure all instances of the macro are replaced where gadget giveback is used. Example call stack: Thread#1: __dwc3_gadget_ep_set_halt() - CLEAR HALT -> dwc3_gadget_ep_cleanup_cancelled_requests() ->list_for_each_entry_safe() ->dwc3_gadget_giveback(n) ->dwc3_gadget_del_and_unmap_request()- n deleted[cancelled_list] ->spin_unlock ->Thread#2 executes ... ->dwc3_gadget_giveback(n+1) ->Already removed! Thread#2: dwc3_gadget_pullup() ->waiting for dwc3 spin_lock ... ->Thread#1 released lock ->dwc3_stop_active_transfers() ->dwc3_remove_requests() ->fetches n+1 item from cancelled_list (n removed by Thread#1) ->dwc3_gadget_giveback() ->dwc3_gadget_del_and_unmap_request()- n+1 deleted[cancelled_list] ->spin_unlock Fixes: d4f1afe5e896 ("usb: dwc3: gadget: move requests to cancelled_list") Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220414183521.23451-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-23usb: dwc3: EP clear halt leading to clearing of delayed_statusWesley Cheng
The usb_ep_clear_halt() API can be called from the function driver, and translates to dwc3_gadget_ep_set_halt(). This routine is shared with when the host issues a clear feature ENDPOINT_HALT, and is differentiated by the protocol argument. If the following sequence occurs, there can be a situation where the delayed_status flag is improperly cleared for the wrong SETUP transaction: 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. Cache the 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. Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220414073902.21960-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-21usb: dwc3: gadget: increase tx fifo size for ss isoc endpointsDan Vacura
Improve performance of isoc transfers in superspeed by increasing the number of possible endpoints available, matching that of what was configured for bulk transfers. Signed-off-by: Dan Vacura <w36195@motorola.com> Link: https://lore.kernel.org/r/20220420183338.445622-1-w36195@motorola.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-21USB / dwc3: Fix three doc-build warningsKushagra Verma
Two kerneldoc comments in gadget.c have excess function parameter description or wrong prototype name and one kerneldoc comment in core.c has an excess function parameter description, resulting in these three doc-build warnings: 1. ./drivers/usb/dwc3/gadget.c:675: warning: Excess function parameter 'nfifos' description in 'dwc3_gadget_calc_tx_fifo_size' 2. ./drivers/usb/dwc3/gadget.c:700: warning: expecting prototype for dwc3_gadget_clear_tx_fifo_size(). Prototype was for dwc3_gadget_clear_tx_fifos() instead 3. ./drivers/usb/dwc3/core.c:347: warning: Excess function parameter 'ref_clk_per' description in 'dwc3_ref_clk_period' Fix the warnings by correcting the prototype name and removing excess parameter descriptions. Signed-off-by: Kushagra Verma <kushagra765@outlook.com> Link: https://lore.kernel.org/r/SI2PR01MB392995043CACD80884A13764F81C9@SI2PR01MB3929.apcprd01.prod.exchangelabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-18usb: dwc3: Issue core soft reset before enabling run/stopWesley Cheng
It is recommended by the Synopsis databook to issue a DCTL.CSftReset when reconnecting from a device-initiated disconnect routine. This resolves issues with enumeration during fast composition switching cases, which result in an unknown device on the host. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220316011358.3057-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15usb: dwc3: gadget: Wait for ep0 xfers to complete during dequeueThinh Nguyen
If a Setup packet is received but yet to DMA out, the controller will not process the End Transfer command of any endpoint. Polling of its DEPCMD.CmdAct may block setting up TRB for Setup packet, causing a command timeout. This may occur if the driver doesn’t service the completion interrupt of the control status stage yet due to system latency, then it won’t prepare TRB and start the transfer for the next Setup Stage. To the host side, the control transfer had completed, and the host can send a new Setup packet at this point. In the meanwhile, if the driver receives an async call to dequeue a request (triggering End Transfer) to any endpoint, then the driver will service that End transfer first, blocking the control status stage completion handler. Since no TRB is available for the Setup stage, the Setup packet can’t be DMA’ed out and the End Transfer gets hung. The driver must not block setting up of the Setup stage. So track and only issue the End Transfer command only when there’s Setup TRB prepared so that the controller can DMA out the Setup packet. Delay the End transfer command if there's no Setup TRB available. This is applicable to all DWC_usb3x IPs. Co-developed-by: Wesley Cheng <quic_wcheng@quicinc.com> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Link: https://lore.kernel.org/r/20220309205402.4467-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15usb: dwc3: gadget: move cmd_endtransfer to extra functionMichael Grzeschik
This patch adds the extra function __dwc3_stop_active_transfer to consolidate the same codepath. Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220306211251.2281335-3-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15usb: dwc3: gadget: ep_queue simplify isoc start conditionMichael Grzeschik
To improve reading the code this patch moves the cases to start_isoc or return the function under one common condition check. Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220306211251.2281335-2-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15usb: dwc3: gadget: Give some time to schedule isocThinh Nguyen
Currently the driver will schedule isoc transfers immediately on the next interval, which is quite aggressive when the interval is 125us. There's report that some platforms may need more time to process the transfer, otherwise the controller may miss the first interval. Let's keep it simple and give the controller at least 500us to schedule the isoc transfer. Link: https://lore.kernel.org/linux-usb/20220302143539.GI11577@pengutronix.de/ Tested-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/deb8146b8e1f7f8495ef2d5647017270934cb2d8.1646708142.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-02-24usb: dwc3: gadget: Let the interrupt handler disable bottom halves.Sebastian Andrzej Siewior
The interrupt service routine registered for the gadget is a primary handler which mask the interrupt source and a threaded handler which handles the source of the interrupt. Since the threaded handler is voluntary threaded, the IRQ-core does not disable bottom halves before invoke the handler like it does for the forced-threaded handler. Due to changes in networking it became visible that a network gadget's completions handler may schedule a softirq which remains unprocessed. The gadget's completion handler is usually invoked either in hard-IRQ or soft-IRQ context. In this context it is enough to just raise the softirq because the softirq itself will be handled once that context is left. In the case of the voluntary threaded handler, there is nothing that will process pending softirqs. Which means it remain queued until another random interrupt (on this CPU) fires and handles it on its exit path or another thread locks and unlocks a lock with the bh suffix. Worst case is that the CPU goes idle and the NOHZ complains about unhandled softirqs. Disable bottom halves before acquiring the lock (and disabling interrupts) and enable them after dropping the lock. This ensures that any pending softirqs will handled right away. Link: https://lkml.kernel.org/r/c2a64979-73d1-2c22-e048-c275c9f81558@samsung.com Fixes: e5f68b4a3e7b0 ("Revert "usb: dwc3: gadget: remove unnecessary _irqsave()"") Cc: stable <stable@kernel.org> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://lore.kernel.org/r/Yg/YPejVQH3KkRVd@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-02-08usb: dwc3: gadget: Prevent core from processing stale TRBsUdipto Goswami
With CPU re-ordering on write instructions, there might be a chance that the HWO is set before the TRB is updated with the new mapped buffer address. And in the case where core is processing a list of TRBs it is possible that it fetched the TRBs when the HWO is set but before the buffer address is updated. Prevent this by adding a memory barrier before the HWO is updated to ensure that the core always process the updated TRBs. Fixes: f6bafc6a1c9d ("usb: dwc3: convert TRBs into bitshifts") Cc: stable <stable@vger.kernel.org> Reviewed-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com> Signed-off-by: Udipto Goswami <quic_ugoswami@quicinc.com> Link: https://lore.kernel.org/r/1644207958-18287-1-git-send-email-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-13usb: dwc3: gadget: Support Multi-Stream TransferThinh Nguyen
Synopsys introduced a new enhancement to DWC_usb32 called Multi-Stream Transfer (MST) to improve bulk streams performance for SuperSpeed and SuperSpeed Plus. This enhancement allows the controller to look ahead and process multiple bulk streams. Previously, to initiate a bulk stream transfer, the driver has to issue Start Transfer command and wait for the stream to complete before initiating a new stream. As a result, the controller does not process TRBs beyond a single stream. With the enhancement, as long as there are new requests, the dwc3 driver can keep preparing new TRBs and the controller can keep caching and processing them without waiting for the transfer completion. The programming flow is similar to regular bulk endpoint with a few additional rules: 1) Chained TRBs of the same stream must have a matching stream ID 2) The last TRB of a stream must have CHN=0 3) All the TRBs with LST=0 must have CSP=1 Depends on the application and usage, internal tests show significant performance improvement in UASP transfers with this enhancement. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/cd9c7a8bf11f790983ac546222dd114893f16b3a.1638242424.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-03usb: dwc3: gadget: Skip reading GEVNTSIZnThinh Nguyen
The driver knows what it needs to set for GEVNTSIZn, and the controller doesn't modify this register unless there's a hard reset. To save a few microseconds of register read in read-modify-write operation, simply do register write with the expected values. This can improve performance when there are many interrupts generated, which the driver needs to check and handle. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/efddf4ee5821c4bc5ae7ad90d629ec7a0ebcbf9a.1638240306.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-03usb: dwc3: gadget: Ignore Update Transfer cmd paramsThinh Nguyen
The controller doesn't check for Update Transfer command parameters DEPCMDPAR{0,1,2}. Writing to these registers is unnecessary. Ignoring this improves performance slightly by removing the register write delay. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/997d9ebf38c6bba920d4ee77bd8c77bf81978a55.1638240306.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-03usb: dwc3: gadget: Skip checking Update Transfer statusThinh Nguyen
If we're not setting CMDACT (from "No Response" Update Transfer command), then there's no point in checking for the command status. So skip it. This can reduce a register read delay and improve performance. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/3dc31cf11581ae3ee82d9202dda3fc17d897d786.1638240306.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-17usb: dwc3: gadget: Fix null pointer exceptionAlbert Wang
In the endpoint interrupt functions dwc3_gadget_endpoint_transfer_in_progress() and dwc3_gadget_endpoint_trbs_complete() will dereference the endpoint descriptor. But it could be cleared in __dwc3_gadget_ep_disable() when accessory disconnected. So we need to check whether it is null or not before dereferencing it. Fixes: f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP queuing while stopping transfers") Cc: stable <stable@vger.kernel.org> Reviewed-by: Jack Pham <quic_jackp@quicinc.com> Signed-off-by: Albert Wang <albertccwang@google.com> Link: https://lore.kernel.org/r/20211109092642.3507692-1-albertccwang@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-17usb: dwc3: gadget: Check for L1/L2/U3 for Start TransferThinh Nguyen
The programming guide noted that the driver needs to verify if the link state is in U0 before executing the Start Transfer command. If it's not in U0, the driver needs to perform remote wakeup. This is not accurate. If the link state is in U1/U2, then the controller will not respond to link recovery request from DCTL.ULSTCHNGREQ. The Start Transfer command will trigger a link recovery if it is in U1/U2. A clarification will be added to the programming guide for all controller versions. The current implementation shouldn't cause any functional issue. It may occasionally report an invalid time out warning from failed link recovery request. The driver will still go ahead with the Start Transfer command if the remote wakeup fails. The new change only initiates remote wakeup where it is needed, which is when the link state is in L1/L2/U3. Fixes: c36d8e947a56 ("usb: dwc3: gadget: put link to U0 before Start Transfer") Cc: <stable@vger.kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/05b4a5fbfbd0863fc9b1d7af934a366219e3d0b4.1635204761.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-17usb: dwc3: gadget: Ignore NoStream after End TransferThinh Nguyen
The End Transfer command from a stream endpoint will generate a NoStream event, and we should ignore it. Currently we set the flag DWC3_EP_IGNORE_NEXT_NOSTREAM to track this prior to sending the command, and it will be cleared on the next stream event. However, a stream event may be generated before the End Transfer command completion and prematurely clear the flag. Fix this by setting the flag on End Transfer completion instead. Fixes: 140ca4cfea8a ("usb: dwc3: gadget: Handle stream transfers") Cc: <stable@vger.kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/cee1253af4c3600edb878d11c9c08b040817ae23.1635203975.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-10-22usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resizedJack Pham
Some functions may dynamically enable and disable their endpoints regularly throughout their operation, particularly when Set Interface is employed to switch between Alternate Settings. For instance the UAC2 function has its respective endpoints for playback & capture associated with AltSetting 1, in which case those endpoints would not get enabled until the host activates the AltSetting. And they conversely become disabled when the interfaces' AltSetting 0 is chosen. With the DWC3 FIFO resizing algorithm recently added, every usb_ep_enable() call results in a call to resize that EP's TXFIFO, but if the same endpoint is enabled again and again, this incorrectly leads to FIFO RAM allocation exhaustion as the mechanism did not account for the possibility that endpoints can be re-enabled many times. Example log splat: dwc3 a600000.dwc3: Fifosize(3717) > RAM size(3462) ep3in depth:217973127 configfs-gadget gadget: u_audio_start_capture:521 Error! dwc3 a600000.dwc3: request 000000000be13e18 was not queued to ep3in Add another bit DWC3_EP_TXFIFO_RESIZED to dep->flags to keep track of whether an EP had already been resized in the current configuration. If so, bail out of dwc3_gadget_resize_tx_fifos() to avoid the calculation error resulting from accumulating the EP's FIFO depth repeatedly. This flag is retained across multiple ep_disable() and ep_enable() calls and is cleared when GTXFIFOSIZn is reset in dwc3_gadget_clear_tx_fifos() upon receiving the next Set Config. Fixes: 9f607a309fbe9 ("usb: dwc3: Resize TX FIFOs to meet EP bursting requirements") Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Jack Pham <jackp@codeaurora.org> Link: https://lore.kernel.org/r/20211021180129.27938-1-jackp@codeaurora.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-10-20usb: dwc3: gadget: Change to dev_dbg() when queuing to inactive gadget/epWesley Cheng
Since function drivers will still be active until dwc3_disconnect_gadget() is called, some applications will continue to queue packets to DWC3 gadget. This can lead to a flood of messages regarding failed ep queue, as the endpoint is in the process of being disabled. Change the log level to debug, so that it can be enabled when debugging issues. Signed-off-by: Wesley Cheng <wcheng@codeaurora.org> Link: https://lore.kernel.org/r/20211018192647.32121-1-wcheng@codeaurora.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-10-11Merge 5.15-rc5 into usb-nextGreg Kroah-Hartman
We need the USB fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-10-05usb: dwc3: gadget: Revert "set gadgets parent to the right controller"Andy Shevchenko
The commit c6e23b89a95d ("usb: dwc3: gadget: set gadgets parent to the right controller") changed the device for the UDC and broke the user space scripts that instantiate the USB gadget(s) via ConfigFS. Revert it for now until the better solution will be proposed. Fixes: c6e23b89a95d ("usb: dwc3: gadget: set gadgets parent to the right controller") Tested-by: Ferry Toth <fntoth@gmail.com> Cc: Michael Grzeschik <m.grzeschik@pengutronix.de> Cc: Felipe Balbi <balbi@kernel.org> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20211004141839.49079-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-09-21usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbindWesley Cheng
There is a race present where the DWC3 runtime resume runs in parallel to the UDC unbind sequence. This will eventually lead to a possible scenario where we are enabling the run/stop bit, without a valid composition defined. Thread#1 (handling UDC unbind): usb_gadget_remove_driver() -->usb_gadget_disconnect() -->dwc3_gadget_pullup(0) --> continue UDC unbind sequence -->Thread#2 is running in parallel here Thread#2 (handing next cable connect) __dwc3_set_mode() -->pm_runtime_get_sync() -->dwc3_gadget_resume() -->dwc->gadget_driver is NOT NULL yet -->dwc3_gadget_run_stop(1) --> _dwc3gadget_start() ... Fix this by tracking the pullup disable routine, and avoiding resuming of the DWC3 gadget. Once the UDC is re-binded, that will trigger the pullup enable routine, which would handle enabling the DWC3 gadget. Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Wesley Cheng <wcheng@codeaurora.org> Link: https://lore.kernel.org/r/20210917021852.2037-1-wcheng@codeaurora.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-09-01Merge tag 'usb-5.15-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB / Thunderbolt updates from Greg KH: "Here is the big set of USB and Thunderbolt patches for 5.15-rc1. Nothing huge in here, just lots of constant forward progress on a number of different drivers and hardware support: - more USB 4/Thunderbolt support added - dwc3 driver updates and additions - usb gadget fixes and addtions for new types - udc gadget driver updates - host controller updates - removal of obsolete drivers - other minor driver updates All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (148 commits) usb: isp1760: otg control register access usb: isp1760: use the right irq status bit usb: isp1760: write to status and address register usb: isp1760: fix qtd fill length usb: isp1760: fix memory pool initialization usb: typec: tcpm: Fix spelling mistake "atleast" -> "at least" usb: dwc2: Fix spelling mistake "was't" -> "wasn't" usb: renesas_usbhs: Fix spelling mistake "faile" -> "failed" usb: host: xhci-rcar: Don't reload firmware after the completion usb: xhci-mtk: allow bandwidth table rollover usb: mtu3: fix random remote wakeup usb: mtu3: return successful suspend status usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint usb: xhci-mtk: modify the SOF/ITP interval for mt8195 usb: xhci-mtk: add a member of num_esit usb: xhci-mtk: check boundary before check tt usb: xhci-mtk: update fs bus bandwidth by bw_budget_table usb: xhci-mtk: fix issue of out-of-bounds array access usb: xhci-mtk: support option to disable usb2 ports usb: xhci-mtk: fix use-after-free of mtk->hcd ...
2021-08-26usb: dwc3: gadget: Stop EP0 transfers during pullup disableWesley Cheng
During a USB cable disconnect, or soft disconnect scenario, a pending SETUP transaction may not be completed, leading to the following error: dwc3 a600000.dwc3: timed out waiting for SETUP phase If this occurs, then the entire pullup disable routine is skipped and proper cleanup and halting of the controller does not complete. Instead of returning an error (which is ignored from the UDC perspective), allow the pullup disable routine to continue, which will also handle disabling of EP0/1. This will end any active transfers as well. Ensure to clear any delayed_status also, as the timeout could happen within the STATUS stage. Fixes: bb0147364850 ("usb: dwc3: gadget: don't clear RUN/STOP when it's invalid to do so") Cc: <stable@vger.kernel.org> Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Wesley Cheng <wcheng@codeaurora.org> Link: https://lore.kernel.org/r/20210825042855.7977-1-wcheng@codeaurora.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-08-26usb: dwc3: gadget: Fix dwc3_calc_trbs_left()Thinh Nguyen
We can't depend on the TRB's HWO bit to determine if the TRB ring is "full". A TRB is only available when the driver had processed it, not when the controller consumed and relinquished the TRB's ownership to the driver. Otherwise, the driver may overwrite unprocessed TRBs. This can happen when many transfer events accumulate and the system is slow to process them and/or when there are too many small requests. If a request is in the started_list, that means there is one or more unprocessed TRBs remained. Check this instead of the TRB's HWO bit whether the TRB ring is full. Fixes: c4233573f6ee ("usb: dwc3: gadget: prepare TRBs on update transfers too") Cc: <stable@vger.kernel.org> Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/e91e975affb0d0d02770686afc3a5b9eb84409f6.1629335416.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>