|
@@ -296,16 +296,18 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci,
|
|
|
unsigned int slot_id,
|
|
|
unsigned int ep_index)
|
|
|
{
|
|
|
- struct xhci_ring *ep_ring;
|
|
|
+ struct xhci_virt_ep *ep;
|
|
|
+ unsigned int ep_state;
|
|
|
u32 field;
|
|
|
__u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
|
|
|
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep = &xhci->devs[slot_id]->eps[ep_index];
|
|
|
+ ep_state = ep->ep_state;
|
|
|
/* Don't ring the doorbell for this endpoint if there are pending
|
|
|
* cancellations because the we don't want to interrupt processing.
|
|
|
*/
|
|
|
- if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)
|
|
|
- && !(ep_ring->state & EP_HALTED)) {
|
|
|
+ if (!ep->cancels_pending && !(ep_state & SET_DEQ_PENDING)
|
|
|
+ && !(ep_state & EP_HALTED)) {
|
|
|
field = xhci_readl(xhci, db_addr) & DB_MASK;
|
|
|
xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
|
|
|
/* Flush PCI posted writes - FIXME Matthew Wilcox says this
|
|
@@ -361,7 +363,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
|
|
|
struct xhci_td *cur_td, struct xhci_dequeue_state *state)
|
|
|
{
|
|
|
struct xhci_virt_device *dev = xhci->devs[slot_id];
|
|
|
- struct xhci_ring *ep_ring = dev->ep_rings[ep_index];
|
|
|
+ struct xhci_ring *ep_ring = dev->eps[ep_index].ring;
|
|
|
struct xhci_generic_trb *trb;
|
|
|
struct xhci_ep_ctx *ep_ctx;
|
|
|
dma_addr_t addr;
|
|
@@ -369,7 +371,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
|
|
|
state->new_cycle_state = 0;
|
|
|
xhci_dbg(xhci, "Finding segment containing stopped TRB.\n");
|
|
|
state->new_deq_seg = find_trb_seg(cur_td->start_seg,
|
|
|
- ep_ring->stopped_trb,
|
|
|
+ dev->eps[ep_index].stopped_trb,
|
|
|
&state->new_cycle_state);
|
|
|
if (!state->new_deq_seg)
|
|
|
BUG();
|
|
@@ -449,9 +451,11 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
|
|
|
union xhci_trb *deq_ptr, u32 cycle_state);
|
|
|
|
|
|
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
|
|
|
- struct xhci_ring *ep_ring, unsigned int slot_id,
|
|
|
- unsigned int ep_index, struct xhci_dequeue_state *deq_state)
|
|
|
+ unsigned int slot_id, unsigned int ep_index,
|
|
|
+ struct xhci_dequeue_state *deq_state)
|
|
|
{
|
|
|
+ struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
|
|
|
+
|
|
|
xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
|
|
|
"new deq ptr = %p (0x%llx dma), new cycle = %u\n",
|
|
|
deq_state->new_deq_seg,
|
|
@@ -468,7 +472,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
|
|
|
* if the ring is running, and ringing the doorbell starts the
|
|
|
* ring running.
|
|
|
*/
|
|
|
- ep_ring->state |= SET_DEQ_PENDING;
|
|
|
+ ep->ep_state |= SET_DEQ_PENDING;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -487,6 +491,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
unsigned int slot_id;
|
|
|
unsigned int ep_index;
|
|
|
struct xhci_ring *ep_ring;
|
|
|
+ struct xhci_virt_ep *ep;
|
|
|
struct list_head *entry;
|
|
|
struct xhci_td *cur_td = 0;
|
|
|
struct xhci_td *last_unlinked_td;
|
|
@@ -499,9 +504,10 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
memset(&deq_state, 0, sizeof(deq_state));
|
|
|
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
|
|
|
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep = &xhci->devs[slot_id]->eps[ep_index];
|
|
|
+ ep_ring = ep->ring;
|
|
|
|
|
|
- if (list_empty(&ep_ring->cancelled_td_list))
|
|
|
+ if (list_empty(&ep->cancelled_td_list))
|
|
|
return;
|
|
|
|
|
|
/* Fix up the ep ring first, so HW stops executing cancelled TDs.
|
|
@@ -509,7 +515,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
* it. We're also in the event handler, so we can't get re-interrupted
|
|
|
* if another Stop Endpoint command completes
|
|
|
*/
|
|
|
- list_for_each(entry, &ep_ring->cancelled_td_list) {
|
|
|
+ list_for_each(entry, &ep->cancelled_td_list) {
|
|
|
cur_td = list_entry(entry, struct xhci_td, cancelled_td_list);
|
|
|
xhci_dbg(xhci, "Cancelling TD starting at %p, 0x%llx (dma).\n",
|
|
|
cur_td->first_trb,
|
|
@@ -518,7 +524,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
* If we stopped on the TD we need to cancel, then we have to
|
|
|
* move the xHC endpoint ring dequeue pointer past this TD.
|
|
|
*/
|
|
|
- if (cur_td == ep_ring->stopped_td)
|
|
|
+ if (cur_td == ep->stopped_td)
|
|
|
xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
|
|
|
&deq_state);
|
|
|
else
|
|
@@ -529,13 +535,13 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
* the cancelled TD list for URB completion later.
|
|
|
*/
|
|
|
list_del(&cur_td->td_list);
|
|
|
- ep_ring->cancels_pending--;
|
|
|
+ ep->cancels_pending--;
|
|
|
}
|
|
|
last_unlinked_td = cur_td;
|
|
|
|
|
|
/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
|
|
|
if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
|
|
|
- xhci_queue_new_dequeue_state(xhci, ep_ring,
|
|
|
+ xhci_queue_new_dequeue_state(xhci,
|
|
|
slot_id, ep_index, &deq_state);
|
|
|
xhci_ring_cmd_db(xhci);
|
|
|
} else {
|
|
@@ -550,7 +556,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
|
|
|
* So stop when we've completed the URB for the last TD we unlinked.
|
|
|
*/
|
|
|
do {
|
|
|
- cur_td = list_entry(ep_ring->cancelled_td_list.next,
|
|
|
+ cur_td = list_entry(ep->cancelled_td_list.next,
|
|
|
struct xhci_td, cancelled_td_list);
|
|
|
list_del(&cur_td->cancelled_td_list);
|
|
|
|
|
@@ -597,7 +603,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
|
|
|
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
|
|
|
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
|
|
|
dev = xhci->devs[slot_id];
|
|
|
- ep_ring = dev->ep_rings[ep_index];
|
|
|
+ ep_ring = dev->eps[ep_index].ring;
|
|
|
ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
|
|
|
slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
|
|
|
|
|
@@ -641,7 +647,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
|
|
|
ep_ctx->deq);
|
|
|
}
|
|
|
|
|
|
- ep_ring->state &= ~SET_DEQ_PENDING;
|
|
|
+ dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
|
|
|
ring_ep_doorbell(xhci, slot_id, ep_index);
|
|
|
}
|
|
|
|
|
@@ -655,7 +661,7 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
|
|
|
|
|
|
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
|
|
|
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
|
|
|
/* This command will only fail if the endpoint wasn't halted,
|
|
|
* but we don't care.
|
|
|
*/
|
|
@@ -673,7 +679,7 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
|
|
|
xhci_ring_cmd_db(xhci);
|
|
|
} else {
|
|
|
/* Clear our internal halted state and restart the ring */
|
|
|
- ep_ring->state &= ~EP_HALTED;
|
|
|
+ xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
|
|
|
ring_ep_doorbell(xhci, slot_id, ep_index);
|
|
|
}
|
|
|
}
|
|
@@ -726,7 +732,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
|
|
|
xhci->devs[slot_id]->in_ctx);
|
|
|
/* Input ctx add_flags are the endpoint index plus one */
|
|
|
ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
|
|
|
if (!ep_ring) {
|
|
|
/* This must have been an initial configure endpoint */
|
|
|
xhci->devs[slot_id]->cmd_status =
|
|
@@ -734,13 +740,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
|
|
|
complete(&xhci->devs[slot_id]->cmd_completion);
|
|
|
break;
|
|
|
}
|
|
|
- ep_state = ep_ring->state;
|
|
|
+ ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
|
|
|
xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
|
|
|
"state = %d\n", ep_index, ep_state);
|
|
|
if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
|
|
|
ep_state & EP_HALTED) {
|
|
|
/* Clear our internal halted state and restart ring */
|
|
|
- xhci->devs[slot_id]->ep_rings[ep_index]->state &=
|
|
|
+ xhci->devs[slot_id]->eps[ep_index].ep_state &=
|
|
|
~EP_HALTED;
|
|
|
ring_ep_doorbell(xhci, slot_id, ep_index);
|
|
|
} else {
|
|
@@ -864,6 +870,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
struct xhci_transfer_event *event)
|
|
|
{
|
|
|
struct xhci_virt_device *xdev;
|
|
|
+ struct xhci_virt_ep *ep;
|
|
|
struct xhci_ring *ep_ring;
|
|
|
unsigned int slot_id;
|
|
|
int ep_index;
|
|
@@ -887,7 +894,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
/* Endpoint ID is 1 based, our index is zero based */
|
|
|
ep_index = TRB_TO_EP_ID(event->flags) - 1;
|
|
|
xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
|
|
|
- ep_ring = xdev->ep_rings[ep_index];
|
|
|
+ ep = &xdev->eps[ep_index];
|
|
|
+ ep_ring = ep->ring;
|
|
|
ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
|
|
|
if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
|
|
|
xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
|
|
@@ -948,7 +956,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
break;
|
|
|
case COMP_STALL:
|
|
|
xhci_warn(xhci, "WARN: Stalled endpoint\n");
|
|
|
- ep_ring->state |= EP_HALTED;
|
|
|
+ ep->ep_state |= EP_HALTED;
|
|
|
status = -EPIPE;
|
|
|
break;
|
|
|
case COMP_TRB_ERR:
|
|
@@ -1016,12 +1024,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
else
|
|
|
td->urb->actual_length = 0;
|
|
|
|
|
|
- ep_ring->stopped_td = td;
|
|
|
- ep_ring->stopped_trb = event_trb;
|
|
|
+ ep->stopped_td = td;
|
|
|
+ ep->stopped_trb = event_trb;
|
|
|
xhci_queue_reset_ep(xhci, slot_id, ep_index);
|
|
|
- xhci_cleanup_stalled_ring(xhci,
|
|
|
- td->urb->dev,
|
|
|
- ep_index, ep_ring);
|
|
|
+ xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
|
|
|
xhci_ring_cmd_db(xhci);
|
|
|
goto td_cleanup;
|
|
|
default:
|
|
@@ -1161,8 +1167,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
* stopped TDs. A stopped TD may be restarted, so don't update
|
|
|
* the ring dequeue pointer or take this TD off any lists yet.
|
|
|
*/
|
|
|
- ep_ring->stopped_td = td;
|
|
|
- ep_ring->stopped_trb = event_trb;
|
|
|
+ ep->stopped_td = td;
|
|
|
+ ep->stopped_trb = event_trb;
|
|
|
} else {
|
|
|
if (trb_comp_code == COMP_STALL ||
|
|
|
trb_comp_code == COMP_BABBLE) {
|
|
@@ -1172,8 +1178,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|
|
* pointer past the TD. We can't do that here because
|
|
|
* the halt condition must be cleared first.
|
|
|
*/
|
|
|
- ep_ring->stopped_td = td;
|
|
|
- ep_ring->stopped_trb = event_trb;
|
|
|
+ ep->stopped_td = td;
|
|
|
+ ep->stopped_trb = event_trb;
|
|
|
} else {
|
|
|
/* Update ring dequeue pointer */
|
|
|
while (ep_ring->dequeue != td->last_trb)
|
|
@@ -1206,7 +1212,7 @@ td_cleanup:
|
|
|
/* Was this TD slated to be cancelled but completed anyway? */
|
|
|
if (!list_empty(&td->cancelled_td_list)) {
|
|
|
list_del(&td->cancelled_td_list);
|
|
|
- ep_ring->cancels_pending--;
|
|
|
+ ep->cancels_pending--;
|
|
|
}
|
|
|
/* Leave the TD around for the reset endpoint function to use
|
|
|
* (but only if it's not a control endpoint, since we already
|
|
@@ -1369,7 +1375,7 @@ static int prepare_transfer(struct xhci_hcd *xhci,
|
|
|
{
|
|
|
int ret;
|
|
|
struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
|
|
|
- ret = prepare_ring(xhci, xdev->ep_rings[ep_index],
|
|
|
+ ret = prepare_ring(xhci, xdev->eps[ep_index].ring,
|
|
|
ep_ctx->ep_info & EP_STATE_MASK,
|
|
|
num_trbs, mem_flags);
|
|
|
if (ret)
|
|
@@ -1389,9 +1395,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
|
|
|
(*td)->urb = urb;
|
|
|
urb->hcpriv = (void *) (*td);
|
|
|
/* Add this TD to the tail of the endpoint ring's TD list */
|
|
|
- list_add_tail(&(*td)->td_list, &xdev->ep_rings[ep_index]->td_list);
|
|
|
- (*td)->start_seg = xdev->ep_rings[ep_index]->enq_seg;
|
|
|
- (*td)->first_trb = xdev->ep_rings[ep_index]->enqueue;
|
|
|
+ list_add_tail(&(*td)->td_list, &xdev->eps[ep_index].ring->td_list);
|
|
|
+ (*td)->start_seg = xdev->eps[ep_index].ring->enq_seg;
|
|
|
+ (*td)->first_trb = xdev->eps[ep_index].ring->enqueue;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1525,7 +1531,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
struct xhci_generic_trb *start_trb;
|
|
|
int start_cycle;
|
|
|
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
|
|
|
num_trbs = count_sg_trbs_needed(xhci, urb);
|
|
|
num_sgs = urb->num_sgs;
|
|
|
|
|
@@ -1658,7 +1664,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
if (urb->sg)
|
|
|
return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
|
|
|
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
|
|
|
|
|
|
num_trbs = 0;
|
|
|
/* How much data is (potentially) left before the 64KB boundary? */
|
|
@@ -1769,7 +1775,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|
|
u32 field, length_field;
|
|
|
struct xhci_td *td;
|
|
|
|
|
|
- ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
|
|
|
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
|
|
|
|
|
|
/*
|
|
|
* Need to copy setup packet into setup TRB, so we can't use the setup
|