1. 26 8月, 2021 2 次提交
  2. 10 8月, 2021 1 次提交
  3. 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
  4. 21 7月, 2021 1 次提交
  5. 11 6月, 2021 1 次提交
  6. 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
  7. 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
  8. 21 5月, 2021 1 次提交
  9. 10 5月, 2021 4 次提交
  10. 23 4月, 2021 1 次提交
  11. 22 4月, 2021 2 次提交
  12. 14 4月, 2021 2 次提交
  13. 02 4月, 2021 1 次提交
  14. 28 3月, 2021 2 次提交
  15. 26 3月, 2021 1 次提交
  16. 23 3月, 2021 5 次提交
  17. 18 3月, 2021 1 次提交
  18. 10 3月, 2021 1 次提交
  19. 09 2月, 2021 2 次提交
  20. 06 2月, 2021 5 次提交
  21. 14 1月, 2021 1 次提交