Skip to content

Commit 9442070

Browse files
committed
Merge tag 'usb-5.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are some small USB fixes for a few reported issues. Included in here are: - xhci fix for a _much_ reported regression. I don't think there's a community distro that has not reported this problem yet :( - new USB quirk addition - cdns3 minor fixes - typec regression fix. All of these have been in linux-next with no reported problems, and the xhci fix has been reported by many to resolve their reported problem" * tag 'usb-5.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: cdnsp: Fix a NULL pointer dereference in cdnsp_endpoint_init() usb: cdns3: gadget: fix new urb never complete if ep cancel previous requests usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub xhci: Fix commad ring abort, write all 64 bits to CRCR register.
2 parents 5163953 + 37307f7 commit 9442070

File tree

4 files changed

+21
-27
lines changed

4 files changed

+21
-27
lines changed

drivers/usb/cdns3/cdns3-gadget.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -337,19 +337,6 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep)
337337
cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs);
338338
}
339339

340-
static void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req)
341-
{
342-
struct cdns3_endpoint *priv_ep = priv_req->priv_ep;
343-
int current_trb = priv_req->start_trb;
344-
345-
while (current_trb != priv_req->end_trb) {
346-
cdns3_ep_inc_deq(priv_ep);
347-
current_trb = priv_ep->dequeue;
348-
}
349-
350-
cdns3_ep_inc_deq(priv_ep);
351-
}
352-
353340
/**
354341
* cdns3_allow_enable_l1 - enable/disable permits to transition to L1.
355342
* @priv_dev: Extended gadget object
@@ -1517,10 +1504,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
15171504

15181505
trb = priv_ep->trb_pool + priv_ep->dequeue;
15191506

1520-
/* Request was dequeued and TRB was changed to TRB_LINK. */
1521-
if (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) {
1507+
/* The TRB was changed as link TRB, and the request was handled at ep_dequeue */
1508+
while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) {
15221509
trace_cdns3_complete_trb(priv_ep, trb);
1523-
cdns3_move_deq_to_next_trb(priv_req);
1510+
cdns3_ep_inc_deq(priv_ep);
1511+
trb = priv_ep->trb_pool + priv_ep->dequeue;
15241512
}
15251513

15261514
if (!request->stream_id) {

drivers/usb/cdns3/cdnsp-mem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,9 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev,
987987

988988
/* Set up the endpoint ring. */
989989
pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags);
990+
if (!pep->ring)
991+
return -ENOMEM;
992+
990993
pep->skip = false;
991994

992995
/* Fill the endpoint context */

drivers/usb/host/xhci-ring.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
366366
/* Must be called with xhci->lock held, releases and aquires lock back */
367367
static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
368368
{
369-
u32 temp_32;
369+
struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg;
370+
union xhci_trb *new_deq = xhci->cmd_ring->dequeue;
371+
u64 crcr;
370372
int ret;
371373

372374
xhci_dbg(xhci, "Abort command ring\n");
@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
375377

376378
/*
377379
* The control bits like command stop, abort are located in lower
378-
* dword of the command ring control register. Limit the write
379-
* to the lower dword to avoid corrupting the command ring pointer
380-
* in case if the command ring is stopped by the time upper dword
381-
* is written.
380+
* dword of the command ring control register.
381+
* Some controllers require all 64 bits to be written to abort the ring.
382+
* Make sure the upper dword is valid, pointing to the next command,
383+
* avoiding corrupting the command ring pointer in case the command ring
384+
* is stopped by the time the upper dword is written.
382385
*/
383-
temp_32 = readl(&xhci->op_regs->cmd_ring);
384-
writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
386+
next_trb(xhci, NULL, &new_seg, &new_deq);
387+
if (trb_is_link(new_deq))
388+
next_trb(xhci, NULL, &new_seg, &new_deq);
389+
390+
crcr = xhci_trb_virt_to_dma(new_seg, new_deq);
391+
xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
385392

386393
/* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
387394
* completion of the Command Abort operation. If CRR is not negated in 5

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4110,11 +4110,7 @@ static void run_state_machine(struct tcpm_port *port)
41104110
tcpm_try_src(port) ? SRC_TRY
41114111
: SNK_ATTACHED,
41124112
0);
4113-
else
4114-
/* Wait for VBUS, but not forever */
4115-
tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON);
41164113
break;
4117-
41184114
case SRC_TRY:
41194115
port->try_src_count++;
41204116
tcpm_set_cc(port, tcpm_rp_cc(port));

0 commit comments

Comments
 (0)