mirror of https://gitee.com/openkylin/linux.git
xhci: remove obsolete dequeue pointer moving code
xhci_find_new_dequeue_state() and xhci_queue_new_dequeue_state() are no longer used afer introducing the move_dequeue_past_td() function. also remove struct xhci_dequeue_state as its no longer used. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20210129130044.206855-26-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d1dbfb942c
commit
741eafb345
|
@ -551,123 +551,6 @@ static u64 xhci_get_hw_deq(struct xhci_hcd *xhci, struct xhci_virt_device *vdev,
|
||||||
return le64_to_cpu(ep_ctx->deq);
|
return le64_to_cpu(ep_ctx->deq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Move the xHC's endpoint ring dequeue pointer past cur_td.
|
|
||||||
* Record the new state of the xHC's endpoint ring dequeue segment,
|
|
||||||
* dequeue pointer, stream id, and new consumer cycle state in state.
|
|
||||||
* Update our internal representation of the ring's dequeue pointer.
|
|
||||||
*
|
|
||||||
* We do this in three jumps:
|
|
||||||
* - First we update our new ring state to be the same as when the xHC stopped.
|
|
||||||
* - Then we traverse the ring to find the segment that contains
|
|
||||||
* the last TRB in the TD. We toggle the xHC's new cycle state when we pass
|
|
||||||
* any link TRBs with the toggle cycle bit set.
|
|
||||||
* - Finally we move the dequeue state one TRB further, toggling the cycle bit
|
|
||||||
* if we've moved it past a link TRB with the toggle cycle bit set.
|
|
||||||
*
|
|
||||||
* Some of the uses of xhci_generic_trb are grotty, but if they're done
|
|
||||||
* with correct __le32 accesses they should work fine. Only users of this are
|
|
||||||
* in here.
|
|
||||||
*/
|
|
||||||
void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
|
|
||||||
unsigned int slot_id, unsigned int ep_index,
|
|
||||||
unsigned int stream_id, struct xhci_td *cur_td,
|
|
||||||
struct xhci_dequeue_state *state)
|
|
||||||
{
|
|
||||||
struct xhci_virt_device *dev = xhci->devs[slot_id];
|
|
||||||
struct xhci_virt_ep *ep = &dev->eps[ep_index];
|
|
||||||
struct xhci_ring *ep_ring;
|
|
||||||
struct xhci_segment *new_seg;
|
|
||||||
union xhci_trb *new_deq;
|
|
||||||
dma_addr_t addr;
|
|
||||||
u64 hw_dequeue;
|
|
||||||
bool cycle_found = false;
|
|
||||||
bool td_last_trb_found = false;
|
|
||||||
|
|
||||||
ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id,
|
|
||||||
ep_index, stream_id);
|
|
||||||
if (!ep_ring) {
|
|
||||||
xhci_warn(xhci, "WARN can't find new dequeue state "
|
|
||||||
"for invalid stream ID %u.\n",
|
|
||||||
stream_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* A cancelled TD can complete with a stall if HW cached the trb.
|
|
||||||
* In this case driver can't find cur_td, but if the ring is empty we
|
|
||||||
* can move the dequeue pointer to the current enqueue position.
|
|
||||||
*/
|
|
||||||
if (!cur_td) {
|
|
||||||
if (list_empty(&ep_ring->td_list)) {
|
|
||||||
state->new_deq_seg = ep_ring->enq_seg;
|
|
||||||
state->new_deq_ptr = ep_ring->enqueue;
|
|
||||||
state->new_cycle_state = ep_ring->cycle_state;
|
|
||||||
goto done;
|
|
||||||
} else {
|
|
||||||
xhci_warn(xhci, "Can't find new dequeue state, missing cur_td\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dig out the cycle state saved by the xHC during the stop ep cmd */
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"Finding endpoint context");
|
|
||||||
|
|
||||||
hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
|
|
||||||
new_seg = ep_ring->deq_seg;
|
|
||||||
new_deq = ep_ring->dequeue;
|
|
||||||
state->new_cycle_state = hw_dequeue & 0x1;
|
|
||||||
state->stream_id = stream_id;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We want to find the pointer, segment and cycle state of the new trb
|
|
||||||
* (the one after current TD's last_trb). We know the cycle state at
|
|
||||||
* hw_dequeue, so walk the ring until both hw_dequeue and last_trb are
|
|
||||||
* found.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
if (!cycle_found && xhci_trb_virt_to_dma(new_seg, new_deq)
|
|
||||||
== (dma_addr_t)(hw_dequeue & ~0xf)) {
|
|
||||||
cycle_found = true;
|
|
||||||
if (td_last_trb_found)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (new_deq == cur_td->last_trb)
|
|
||||||
td_last_trb_found = true;
|
|
||||||
|
|
||||||
if (cycle_found && trb_is_link(new_deq) &&
|
|
||||||
link_trb_toggles_cycle(new_deq))
|
|
||||||
state->new_cycle_state ^= 0x1;
|
|
||||||
|
|
||||||
next_trb(xhci, ep_ring, &new_seg, &new_deq);
|
|
||||||
|
|
||||||
/* Search wrapped around, bail out */
|
|
||||||
if (new_deq == ep->ring->dequeue) {
|
|
||||||
xhci_err(xhci, "Error: Failed finding new dequeue state\n");
|
|
||||||
state->new_deq_seg = NULL;
|
|
||||||
state->new_deq_ptr = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (!cycle_found || !td_last_trb_found);
|
|
||||||
|
|
||||||
state->new_deq_seg = new_seg;
|
|
||||||
state->new_deq_ptr = new_deq;
|
|
||||||
|
|
||||||
done:
|
|
||||||
/* Don't update the ring cycle state for the producer (us). */
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"Cycle state = 0x%x", state->new_cycle_state);
|
|
||||||
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"New dequeue segment = %p (virtual)",
|
|
||||||
state->new_deq_seg);
|
|
||||||
addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr);
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"New dequeue pointer = 0x%llx (DMA)",
|
|
||||||
(unsigned long long) addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
|
static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
|
||||||
unsigned int slot_id, unsigned int ep_index,
|
unsigned int slot_id, unsigned int ep_index,
|
||||||
unsigned int stream_id, struct xhci_td *td)
|
unsigned int stream_id, struct xhci_td *td)
|
||||||
|
@ -4418,71 +4301,6 @@ int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
||||||
trb_slot_id | trb_ep_index | type | trb_suspend, false);
|
trb_slot_id | trb_ep_index | type | trb_suspend, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Transfer Ring Dequeue Pointer command */
|
|
||||||
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
|
|
||||||
unsigned int slot_id, unsigned int ep_index,
|
|
||||||
struct xhci_dequeue_state *deq_state)
|
|
||||||
{
|
|
||||||
dma_addr_t addr;
|
|
||||||
u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);
|
|
||||||
u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);
|
|
||||||
u32 trb_stream_id = STREAM_ID_FOR_TRB(deq_state->stream_id);
|
|
||||||
u32 trb_sct = 0;
|
|
||||||
u32 type = TRB_TYPE(TRB_SET_DEQ);
|
|
||||||
struct xhci_virt_ep *ep;
|
|
||||||
struct xhci_command *cmd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), new deq ptr = %p (0x%llx dma), new cycle = %u",
|
|
||||||
deq_state->new_deq_seg,
|
|
||||||
(unsigned long long)deq_state->new_deq_seg->dma,
|
|
||||||
deq_state->new_deq_ptr,
|
|
||||||
(unsigned long long)xhci_trb_virt_to_dma(
|
|
||||||
deq_state->new_deq_seg, deq_state->new_deq_ptr),
|
|
||||||
deq_state->new_cycle_state);
|
|
||||||
|
|
||||||
addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
|
|
||||||
deq_state->new_deq_ptr);
|
|
||||||
if (addr == 0) {
|
|
||||||
xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
|
|
||||||
xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n",
|
|
||||||
deq_state->new_deq_seg, deq_state->new_deq_ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ep = &xhci->devs[slot_id]->eps[ep_index];
|
|
||||||
if ((ep->ep_state & SET_DEQ_PENDING)) {
|
|
||||||
xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
|
|
||||||
xhci_warn(xhci, "A Set TR Deq Ptr command is pending.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function gets called from contexts where it cannot sleep */
|
|
||||||
cmd = xhci_alloc_command(xhci, false, GFP_ATOMIC);
|
|
||||||
if (!cmd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ep->queued_deq_seg = deq_state->new_deq_seg;
|
|
||||||
ep->queued_deq_ptr = deq_state->new_deq_ptr;
|
|
||||||
if (deq_state->stream_id)
|
|
||||||
trb_sct = SCT_FOR_TRB(SCT_PRI_TR);
|
|
||||||
ret = queue_command(xhci, cmd,
|
|
||||||
lower_32_bits(addr) | trb_sct | deq_state->new_cycle_state,
|
|
||||||
upper_32_bits(addr), trb_stream_id,
|
|
||||||
trb_slot_id | trb_ep_index | type, false);
|
|
||||||
if (ret < 0) {
|
|
||||||
xhci_free_command(xhci, cmd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop the TD queueing code from ringing the doorbell until
|
|
||||||
* this command completes. The HC won't set the dequeue pointer
|
|
||||||
* if the ring is running, and ringing the doorbell starts the
|
|
||||||
* ring running.
|
|
||||||
*/
|
|
||||||
ep->ep_state |= SET_DEQ_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
||||||
int slot_id, unsigned int ep_index,
|
int slot_id, unsigned int ep_index,
|
||||||
enum xhci_ep_reset_type reset_type)
|
enum xhci_ep_reset_type reset_type)
|
||||||
|
|
|
@ -1571,13 +1571,6 @@ struct xhci_cd {
|
||||||
union xhci_trb *cmd_trb;
|
union xhci_trb *cmd_trb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xhci_dequeue_state {
|
|
||||||
struct xhci_segment *new_deq_seg;
|
|
||||||
union xhci_trb *new_deq_ptr;
|
|
||||||
int new_cycle_state;
|
|
||||||
unsigned int stream_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum xhci_ring_type {
|
enum xhci_ring_type {
|
||||||
TYPE_CTRL = 0,
|
TYPE_CTRL = 0,
|
||||||
TYPE_ISOC,
|
TYPE_ISOC,
|
||||||
|
@ -2132,13 +2125,6 @@ int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
||||||
enum xhci_ep_reset_type reset_type);
|
enum xhci_ep_reset_type reset_type);
|
||||||
int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd,
|
||||||
u32 slot_id);
|
u32 slot_id);
|
||||||
void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
|
|
||||||
unsigned int slot_id, unsigned int ep_index,
|
|
||||||
unsigned int stream_id, struct xhci_td *cur_td,
|
|
||||||
struct xhci_dequeue_state *state);
|
|
||||||
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
|
|
||||||
unsigned int slot_id, unsigned int ep_index,
|
|
||||||
struct xhci_dequeue_state *deq_state);
|
|
||||||
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
|
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
|
||||||
unsigned int ep_index, unsigned int stream_id,
|
unsigned int ep_index, unsigned int stream_id,
|
||||||
struct xhci_td *td);
|
struct xhci_td *td);
|
||||||
|
|
Loading…
Reference in New Issue