1. 08 2月, 2022 1 次提交
  2. 13 12月, 2021 1 次提交
    • T
      usb: dwc3: gadget: Support Multi-Stream Transfer · 666f3de7
      Thinh 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: NThinh Nguyen <Thinh.Nguyen@synopsys.com>
      Link: https://lore.kernel.org/r/cd9c7a8bf11f790983ac546222dd114893f16b3a.1638242424.git.Thinh.Nguyen@synopsys.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      666f3de7
  3. 03 12月, 2021 3 次提交
  4. 17 11月, 2021 3 次提交
  5. 22 10月, 2021 1 次提交
    • J
      usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resized · 876a75cb
      Jack 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: 9f607a30 ("usb: dwc3: Resize TX FIFOs to meet EP bursting requirements")
      Reviewed-by: NThinh Nguyen <Thinh.Nguyen@synopsys.com>
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Link: https://lore.kernel.org/r/20211021180129.27938-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      876a75cb
  6. 21 10月, 2021 1 次提交
  7. 05 10月, 2021 1 次提交
  8. 21 9月, 2021 1 次提交
  9. 26 8月, 2021 2 次提交
  10. 10 8月, 2021 1 次提交
  11. 05 8月, 2021 2 次提交
    • W
      usb: dwc3: gadget: Avoid runtime resume if disabling pullup · cb10f68a
      Wesley Cheng 提交于
      If the device is already in the runtime suspended state, any call to
      the pullup routine will issue a runtime resume on the DWC3 core
      device.  If the USB gadget is disabling the pullup, then avoid having
      to issue a runtime resume, as DWC3 gadget has already been
      halted/stopped.
      
      This fixes an issue where the following condition occurs:
      
      usb_gadget_remove_driver()
      -->usb_gadget_disconnect()
       -->dwc3_gadget_pullup(0)
        -->pm_runtime_get_sync() -> ret = 0
        -->pm_runtime_put() [async]
      -->usb_gadget_udc_stop()
       -->dwc3_gadget_stop()
        -->dwc->gadget_driver = NULL
      ...
      
      dwc3_suspend_common()
      -->dwc3_gadget_suspend()
       -->DWC3 halt/stop routine skipped, driver_data == NULL
      
      This leads to a situation where the DWC3 gadget is not properly
      stopped, as the runtime resume would have re-enabled EP0 and event
      interrupts, and since we avoided the DWC3 gadget suspend, these
      resources were never disabled.
      
      Fixes: 77adb8bd ("usb: dwc3: gadget: Allow runtime suspend if UDC unbinded")
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NFelipe Balbi <balbi@kernel.org>
      Signed-off-by: NWesley Cheng <wcheng@codeaurora.org>
      Link: https://lore.kernel.org/r/1628058245-30692-1-git-send-email-wcheng@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      cb10f68a
    • W
      usb: dwc3: gadget: Use list_replace_init() before traversing lists · d25d8506
      Wesley 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
      
      Fix this condition by utilizing list_replace_init(), and traversing
      through a local copy of the current elements in the endpoint lists.
      This will also set the parent list as empty, so if another thread is
      also looping through the list, it will be empty on the next iteration.
      
      Fixes: d4f1afe5 ("usb: dwc3: gadget: move requests to cancelled_list")
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NFelipe Balbi <balbi@kernel.org>
      Signed-off-by: NWesley Cheng <wcheng@codeaurora.org>
      Link: https://lore.kernel.org/r/1627543994-20327-1-git-send-email-wcheng@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d25d8506
  12. 27 7月, 2021 1 次提交
  13. 21 7月, 2021 1 次提交
  14. 12 7月, 2021 1 次提交
  15. 11 6月, 2021 1 次提交
  16. 04 6月, 2021 1 次提交
    • J
      usb: dwc3: debugfs: Add and remove endpoint dirs dynamically · 8d396bb0
      Jack Pham 提交于
      The DWC3 DebugFS directory and files are currently created once
      during probe.  This includes creation of subdirectories for each
      of the gadget's endpoints.  This works fine for peripheral-only
      controllers, as dwc3_core_init_mode() calls dwc3_gadget_init()
      just prior to calling dwc3_debugfs_init().
      
      However, for dual-role controllers, dwc3_core_init_mode() will
      instead call dwc3_drd_init() which is problematic in a few ways.
      First, the initial state must be determined, then dwc3_set_mode()
      will have to schedule drd_work and by then dwc3_debugfs_init()
      could have already been invoked.  Even if the initial mode is
      peripheral, dwc3_gadget_init() happens after the DebugFS files
      are created, and worse so if the initial state is host and the
      controller switches to peripheral much later.  And secondly,
      even if the gadget endpoints' debug entries were successfully
      created, if the controller exits peripheral mode, its dwc3_eps
      are freed so the debug files would now hold stale references.
      
      So it is best if the DebugFS endpoint entries are created and
      removed dynamically at the same time the underlying dwc3_eps are.
      Do this by calling dwc3_debugfs_create_endpoint_dir() as each
      endpoint is created, and conversely remove the DebugFS entry when
      the endpoint is freed.
      
      Fixes: 41ce1456 ("usb: dwc3: core: make dwc3_set_mode() work properly")
      Cc: stable <stable@vger.kernel.org>
      Reviewed-by: NPeter Chen <peter.chen@kernel.org>
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Link: https://lore.kernel.org/r/20210529192932.22912-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8d396bb0
  17. 02 6月, 2021 3 次提交
    • J
      usb: dwc3: gadget: Bail from dwc3_gadget_exit() if dwc->gadget is NULL · 03715ea2
      Jack Pham 提交于
      There exists a possible scenario in which dwc3_gadget_init() can fail:
      during during host -> peripheral mode switch in dwc3_set_mode(), and
      a pending gadget driver fails to bind.  Then, if the DRD undergoes
      another mode switch from peripheral->host the resulting
      dwc3_gadget_exit() will attempt to reference an invalid and dangling
      dwc->gadget pointer as well as call dma_free_coherent() on unmapped
      DMA pointers.
      
      The exact scenario can be reproduced as follows:
       - Start DWC3 in peripheral mode
       - Configure ConfigFS gadget with FunctionFS instance (or use g_ffs)
       - Run FunctionFS userspace application (open EPs, write descriptors, etc)
       - Bind gadget driver to DWC3's UDC
       - Switch DWC3 to host mode
         => dwc3_gadget_exit() is called. usb_del_gadget() will put the
      	ConfigFS driver instance on the gadget_driver_pending_list
       - Stop FunctionFS application (closes the ep files)
       - Switch DWC3 to peripheral mode
         => dwc3_gadget_init() fails as usb_add_gadget() calls
      	check_pending_gadget_drivers() and attempts to rebind the UDC
      	to the ConfigFS gadget but fails with -19 (-ENODEV) because the
      	FFS instance is not in FFS_ACTIVE state (userspace has not
      	re-opened and written the descriptors yet, i.e. desc_ready!=0).
       - Switch DWC3 back to host mode
         => dwc3_gadget_exit() is called again, but this time dwc->gadget
      	is invalid.
      
      Although it can be argued that userspace should take responsibility
      for ensuring that the FunctionFS application be ready prior to
      allowing the composite driver bind to the UDC, failure to do so
      should not result in a panic from the kernel driver.
      
      Fix this by setting dwc->gadget to NULL in the failure path of
      dwc3_gadget_init() and add a check to dwc3_gadget_exit() to bail out
      unless the gadget pointer is valid.
      
      Fixes: e81a7018 ("usb: dwc3: allocate gadget structure dynamically")
      Cc: <stable@vger.kernel.org>
      Reviewed-by: NPeter Chen <peter.chen@kernel.org>
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Link: https://lore.kernel.org/r/20210528160405.17550-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      03715ea2
    • W
      usb: dwc3: gadget: Disable gadget IRQ during pullup disable · 82129373
      Wesley Cheng 提交于
      Current sequence utilizes dwc3_gadget_disable_irq() alongside
      synchronize_irq() to ensure that no further DWC3 events are generated.
      However, the dwc3_gadget_disable_irq() API only disables device
      specific events.  Endpoint events can still be generated.  Briefly
      disable the interrupt line, so that the cleanup code can run to
      prevent device and endpoint events. (i.e. __dwc3_gadget_stop() and
      dwc3_stop_active_transfers() respectively)
      
      Without doing so, it can lead to both the interrupt handler and the
      pullup disable routine both writing to the GEVNTCOUNT register, which
      will cause an incorrect count being read from future interrupts.
      
      Fixes: ae7e8610 ("usb: dwc3: Stop active transfers before halting the controller")
      Signed-off-by: NWesley Cheng <wcheng@codeaurora.org>
      Link: https://lore.kernel.org/r/1621571037-1424-1-git-send-email-wcheng@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      82129373
    • J
      usb: dwc3: debugfs: Add and remove endpoint dirs dynamically · 5ff90af9
      Jack Pham 提交于
      The DWC3 DebugFS directory and files are currently created once
      during probe.  This includes creation of subdirectories for each
      of the gadget's endpoints.  This works fine for peripheral-only
      controllers, as dwc3_core_init_mode() calls dwc3_gadget_init()
      just prior to calling dwc3_debugfs_init().
      
      However, for dual-role controllers, dwc3_core_init_mode() will
      instead call dwc3_drd_init() which is problematic in a few ways.
      First, the initial state must be determined, then dwc3_set_mode()
      will have to schedule drd_work and by then dwc3_debugfs_init()
      could have already been invoked.  Even if the initial mode is
      peripheral, dwc3_gadget_init() happens after the DebugFS files
      are created, and worse so if the initial state is host and the
      controller switches to peripheral much later.  And secondly,
      even if the gadget endpoints' debug entries were successfully
      created, if the controller exits peripheral mode, its dwc3_eps
      are freed so the debug files would now hold stale references.
      
      So it is best if the DebugFS endpoint entries are created and
      removed dynamically at the same time the underlying dwc3_eps are.
      Do this by calling dwc3_debugfs_create_endpoint_dir() as each
      endpoint is created, and conversely remove the DebugFS entry when
      the endpoint is freed.
      
      Fixes: 41ce1456 ("usb: dwc3: core: make dwc3_set_mode() work properly")
      Reviewed-by: NPeter Chen <peter.chen@kernel.org>
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Link: https://lore.kernel.org/r/20210529192932.22912-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      5ff90af9
  18. 21 5月, 2021 1 次提交
  19. 10 5月, 2021 4 次提交
  20. 23 4月, 2021 1 次提交
  21. 22 4月, 2021 2 次提交
  22. 14 4月, 2021 2 次提交
  23. 02 4月, 2021 1 次提交
  24. 28 3月, 2021 2 次提交
  25. 26 3月, 2021 1 次提交
  26. 23 3月, 2021 1 次提交