There is a possibility of race between endpoint transfer
completion context and stop active transfer context. As
a result dwc3_gadget_ep_cleanup_completed_requests() iterates
over started_list using list_for_each_safe while
dwc3_remove_requests() is deleting req from started list.
While iterating over current list node list_for_each_safe caches
next list node. If the cached list node is getting deleted by
dwc3_remove_requests() then request for same list node would be
given back as part of endpoint transfer completion. This result
into list_del corruption because list node is getting deleted
twice. Fix this issue by iterating started_list using while loop
and always accessing first node from list head.
Change-Id: I64104a43ade015923deeb1f230a17dea08817052
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
There still exists a small window in which dwc3_gadget_pullup()
is called while a new control transfer setup packet had newly
arrived. In the case where it needs to be delegated to the gadget
driver, it releases dwc3->lock and allows pullup() to proceed to
call run_stop() to attempt to stop the controller. The lock will
get released again when calling dwc3_stop_active_transfers()
which allows the gadget driver to meanwhile call ep_queue() for
a three-stage control transfer and sneak in a Start Transfer. By
the time the DCTL register is written, the controller will fail
to halt due to having an outstanding transfer in progress.
CPU0 CPU1
...dwc3->lock held...
dwc3_ep0_inspect_setup() dwc3_gadget_pullup()
dwc3_ep0_delegate_req() spin_lock_irq_save()
spin_unlock() ... unblocked
composite_setup() dwc3_gadget_run_stop()
usb_ep_queue() dwc3_stop_active_transfers()
dwc3_gadget_ep0_queue() dwc3_gadget_remove_requests()
spin_lock_irqsave() dwc3_gadget_giveback()
... unblocked spin_unlock()
__dwc3_ep0_do_control_data() spin_lock()
issues Start Transfer
spin_unlock_irqrestore() ... unblocked
spin_lock() clear DCTL_RUN_STOP
... wait for DSTS_DEVCTRLHLT
time out
This change attempts to fix the issue by additionally checking
the dwc->ep0_next_event state in dwc3_gadget_pullup() to catch
the case when a SETUP packet had just been received and handled
by dwc3_ep0_inspect_setup but is still waiting to proceed to
either a DATA or STATUS stage. This allows pullup() to wait for
completion of the transfer before moving on to clear run/stop.
Change-Id: Ib2da3c86213ade1a61fb82f95a1f7c9534d9df3f
Signed-off-by: Jack Pham <jackp@codeaurora.org>
if USB bus reset is received from Host in middle of control transfer
request, 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.
Change-Id: Idf8adf3c2416e7945d879bf88c321e1eea3c31d4
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
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 my issuing stall and restart on ep0 if it
is not in setup phase.
CRs-Fixed: 2136658
Change-Id: I6dc20c2735a6ce772533ccb5b63ba5d1b01f89d7
Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
USB IN/INT endpoint stalls when performing TX FIFO resize functionality
when IN/INT endpoint is already active i.e. usb endpoint is enabled and
usb request is pending with it. Fix this issue by making sure that TX
FIFO resize is performed before enabling endpoint which shall happen
after set_alt(1) and before any function queues request with its
allocated USB endpoint.
This commit also squashes the following commits from previous kernels:
Revert "usb: dwc3: drop FIFO resizing logic"
dwc3: gadget: Improve TX FIFO resize functionality
dwc3: gadget: Use default TX FIFO size as 1024 bytes with each IN eps
usb: gadget: Use mult as 3 for GSI related USB IN endpoint always
USB: dwc3: gadget: Fix TxFIFO resizing logic
dwc3: Preserve TxFIFO of IN/INT EP for UDC without tx-fifo-resize
dwc3: gadget: Use TXFIFO register based on used dwc3 version
dwc3: gadget: Increase TXFIFO size as 6KB for GSI IN endpoint
usb: dwc3: Change TXFIFO size for GSI IN EP based on controller
usb: dwc3: gadget: Fix TXFIFO resize logic for non-zero EPs
usb: dwc3: Increase the TxFIFO resize factor
Change-Id: I13a590f87ab8492f7c95a15b2da9f00c9c63c4f9
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
This change adds the following QTI MSM platform specific features
to the USB DWC3 core & gadget drivers:
- BAM/DBM endpoint support
- GSI endpoint support
- low power mode
- glue layer notifications
- high speed-only fallback
- additional debug logging
Change-Id: I0f733d05f3f88a4a734d8489b5eb548391ab3af3
Signed-off-by: Jack Pham <jackp@codeaurora.org>