usb: cdnsp: Fix issue with Clear Feature Halt Endpoint
authorPawel Laszczak <pawell@cadence.com>
Thu, 10 Nov 2022 06:30:05 +0000 (01:30 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Nov 2022 15:51:26 +0000 (16:51 +0100)
During handling Clear Halt Endpoint Feature request, driver invokes
Reset Endpoint command. Because this command has some issue with
transition endpoint from Running to Idle state the driver must
stop the endpoint by using Stop Endpoint command.

cc: <stable@vger.kernel.org>
Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Link: https://lore.kernel.org/r/20221110063005.370656-1-pawell@cadence.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/cdns3/cdnsp-gadget.c
drivers/usb/cdns3/cdnsp-ring.c

index c67715f6f756dba557c2151a8d7047b7b608690f..f9aa50ff14d42bfcdeed861f2e71d3581b5cf0e4 100644 (file)
@@ -600,11 +600,11 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
 
        trace_cdnsp_ep_halt(value ? "Set" : "Clear");
 
-       if (value) {
-               ret = cdnsp_cmd_stop_ep(pdev, pep);
-               if (ret)
-                       return ret;
+       ret = cdnsp_cmd_stop_ep(pdev, pep);
+       if (ret)
+               return ret;
 
+       if (value) {
                if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
                        cdnsp_queue_halt_endpoint(pdev, pep->idx);
                        cdnsp_ring_cmd_db(pdev);
@@ -613,10 +613,6 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
 
                pep->ep_state |= EP_HALTED;
        } else {
-               /*
-                * In device mode driver can call reset endpoint command
-                * from any endpoint state.
-                */
                cdnsp_queue_reset_ep(pdev, pep->idx);
                cdnsp_ring_cmd_db(pdev);
                ret = cdnsp_wait_for_cmd_compl(pdev);
index 794e413800ae8239ac8ce2d92de8ddb8c6620345..04dfcaa08dc45b9f881d0931d56bd70e0c69d3b3 100644 (file)
@@ -2076,7 +2076,8 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
        u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx);
        int ret = 0;
 
-       if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) {
+       if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED ||
+           ep_state == EP_STATE_HALTED) {
                trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx);
                goto ep_stopped;
        }