Commit 94420704 authored by Linus Torvalds's avatar Linus Torvalds

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.
parents 51639539 37307f70
...@@ -337,19 +337,6 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep) ...@@ -337,19 +337,6 @@ static void cdns3_ep_inc_deq(struct cdns3_endpoint *priv_ep)
cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs); cdns3_ep_inc_trb(&priv_ep->dequeue, &priv_ep->ccs, priv_ep->num_trbs);
} }
static void cdns3_move_deq_to_next_trb(struct cdns3_request *priv_req)
{
struct cdns3_endpoint *priv_ep = priv_req->priv_ep;
int current_trb = priv_req->start_trb;
while (current_trb != priv_req->end_trb) {
cdns3_ep_inc_deq(priv_ep);
current_trb = priv_ep->dequeue;
}
cdns3_ep_inc_deq(priv_ep);
}
/** /**
* cdns3_allow_enable_l1 - enable/disable permits to transition to L1. * cdns3_allow_enable_l1 - enable/disable permits to transition to L1.
* @priv_dev: Extended gadget object * @priv_dev: Extended gadget object
...@@ -1517,10 +1504,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, ...@@ -1517,10 +1504,11 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
trb = priv_ep->trb_pool + priv_ep->dequeue; trb = priv_ep->trb_pool + priv_ep->dequeue;
/* Request was dequeued and TRB was changed to TRB_LINK. */ /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */
if (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) {
trace_cdns3_complete_trb(priv_ep, trb); trace_cdns3_complete_trb(priv_ep, trb);
cdns3_move_deq_to_next_trb(priv_req); cdns3_ep_inc_deq(priv_ep);
trb = priv_ep->trb_pool + priv_ep->dequeue;
} }
if (!request->stream_id) { if (!request->stream_id) {
......
...@@ -987,6 +987,9 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev, ...@@ -987,6 +987,9 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev,
/* Set up the endpoint ring. */ /* Set up the endpoint ring. */
pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags); pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags);
if (!pep->ring)
return -ENOMEM;
pep->skip = false; pep->skip = false;
/* Fill the endpoint context */ /* Fill the endpoint context */
......
...@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, ...@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
/* Must be called with xhci->lock held, releases and aquires lock back */ /* Must be called with xhci->lock held, releases and aquires lock back */
static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
{ {
u32 temp_32; struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg;
union xhci_trb *new_deq = xhci->cmd_ring->dequeue;
u64 crcr;
int ret; int ret;
xhci_dbg(xhci, "Abort command ring\n"); xhci_dbg(xhci, "Abort command ring\n");
...@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) ...@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
/* /*
* The control bits like command stop, abort are located in lower * The control bits like command stop, abort are located in lower
* dword of the command ring control register. Limit the write * dword of the command ring control register.
* to the lower dword to avoid corrupting the command ring pointer * Some controllers require all 64 bits to be written to abort the ring.
* in case if the command ring is stopped by the time upper dword * Make sure the upper dword is valid, pointing to the next command,
* is written. * avoiding corrupting the command ring pointer in case the command ring
* is stopped by the time the upper dword is written.
*/ */
temp_32 = readl(&xhci->op_regs->cmd_ring); next_trb(xhci, NULL, &new_seg, &new_deq);
writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); if (trb_is_link(new_deq))
next_trb(xhci, NULL, &new_seg, &new_deq);
crcr = xhci_trb_virt_to_dma(new_seg, new_deq);
xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
/* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
* completion of the Command Abort operation. If CRR is not negated in 5 * completion of the Command Abort operation. If CRR is not negated in 5
......
...@@ -4110,11 +4110,7 @@ static void run_state_machine(struct tcpm_port *port) ...@@ -4110,11 +4110,7 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_try_src(port) ? SRC_TRY tcpm_try_src(port) ? SRC_TRY
: SNK_ATTACHED, : SNK_ATTACHED,
0); 0);
else
/* Wait for VBUS, but not forever */
tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON);
break; break;
case SRC_TRY: case SRC_TRY:
port->try_src_count++; port->try_src_count++;
tcpm_set_cc(port, tcpm_rp_cc(port)); tcpm_set_cc(port, tcpm_rp_cc(port));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment