aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2012-03-05 04:49:34 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-03-13 12:29:55 -0400
commitb008df60c6369ba0290fa7daa177375407a12e07 (patch)
tree05a59c4a4d8d624b18ad0844949841f36b241c17
parent3fe4fe083d3355537565b2b0a678807513dfa013 (diff)
xHCI: count free TRBs on transfer ring
In the past, the room_on_ring() check was implemented by walking all over the ring, which is wasteful and complicated. Count the number of free TRBs instead. The free TRBs number should be updated when enqueue/dequeue pointer is updated, or upon the completion of a set dequeue pointer command. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Tested-by: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
-rw-r--r--drivers/usb/host/xhci-mem.c6
-rw-r--r--drivers/usb/host/xhci-ring.c105
-rw-r--r--drivers/usb/host/xhci.c1
-rw-r--r--drivers/usb/host/xhci.h2
4 files changed, 67 insertions, 47 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bdea4de867b4..212012c97df3 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -135,6 +135,12 @@ static void xhci_initialize_ring_info(struct xhci_ring *ring)
135 /* Not necessary for new rings, but needed for re-initialized rings */ 135 /* Not necessary for new rings, but needed for re-initialized rings */
136 ring->enq_updates = 0; 136 ring->enq_updates = 0;
137 ring->deq_updates = 0; 137 ring->deq_updates = 0;
138
139 /*
140 * Each segment has a link TRB, and leave an extra TRB for SW
141 * accounting purpose
142 */
143 ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
138} 144}
139 145
140/** 146/**
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ad68a28d8fe6..f9b6fa364f22 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -145,10 +145,17 @@ static void next_trb(struct xhci_hcd *xhci,
145 */ 145 */
146static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) 146static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
147{ 147{
148 union xhci_trb *next = ++(ring->dequeue); 148 union xhci_trb *next;
149 unsigned long long addr; 149 unsigned long long addr;
150 150
151 ring->deq_updates++; 151 ring->deq_updates++;
152
153 /* If this is not event ring, there is one more usable TRB */
154 if (ring->type != TYPE_EVENT &&
155 !last_trb(xhci, ring, ring->deq_seg, ring->dequeue))
156 ring->num_trbs_free++;
157 next = ++(ring->dequeue);
158
152 /* Update the dequeue pointer further if that was a link TRB or we're at 159 /* Update the dequeue pointer further if that was a link TRB or we're at
153 * the end of an event ring segment (which doesn't have link TRBS) 160 * the end of an event ring segment (which doesn't have link TRBS)
154 */ 161 */
@@ -189,6 +196,10 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
189 unsigned long long addr; 196 unsigned long long addr;
190 197
191 chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN; 198 chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN;
199 /* If this is not event ring, there is one less usable TRB */
200 if (ring->type != TYPE_EVENT &&
201 !last_trb(xhci, ring, ring->enq_seg, ring->enqueue))
202 ring->num_trbs_free--;
192 next = ++(ring->enqueue); 203 next = ++(ring->enqueue);
193 204
194 ring->enq_updates++; 205 ring->enq_updates++;
@@ -240,54 +251,14 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
240/* 251/*
241 * Check to see if there's room to enqueue num_trbs on the ring. See rules 252 * Check to see if there's room to enqueue num_trbs on the ring. See rules
242 * above. 253 * above.
243 * FIXME: this would be simpler and faster if we just kept track of the number
244 * of free TRBs in a ring.
245 */ 254 */
246static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, 255static inline int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
247 unsigned int num_trbs) 256 unsigned int num_trbs)
248{ 257{
249 int i; 258 if (ring->num_trbs_free >= num_trbs)
250 union xhci_trb *enq = ring->enqueue;
251 struct xhci_segment *enq_seg = ring->enq_seg;
252 struct xhci_segment *cur_seg;
253 unsigned int left_on_ring;
254
255 /* If we are currently pointing to a link TRB, advance the
256 * enqueue pointer before checking for space */
257 while (last_trb(xhci, ring, enq_seg, enq)) {
258 enq_seg = enq_seg->next;
259 enq = enq_seg->trbs;
260 }
261
262 /* Check if ring is empty */
263 if (enq == ring->dequeue) {
264 /* Can't use link trbs */
265 left_on_ring = TRBS_PER_SEGMENT - 1;
266 for (cur_seg = enq_seg->next; cur_seg != enq_seg;
267 cur_seg = cur_seg->next)
268 left_on_ring += TRBS_PER_SEGMENT - 1;
269
270 /* Always need one TRB free in the ring. */
271 left_on_ring -= 1;
272 if (num_trbs > left_on_ring) {
273 xhci_warn(xhci, "Not enough room on ring; "
274 "need %u TRBs, %u TRBs left\n",
275 num_trbs, left_on_ring);
276 return 0;
277 }
278 return 1; 259 return 1;
279 } 260
280 /* Make sure there's an extra empty TRB available */ 261 return 0;
281 for (i = 0; i <= num_trbs; ++i) {
282 if (enq == ring->dequeue)
283 return 0;
284 enq++;
285 while (last_trb(xhci, ring, enq_seg, enq)) {
286 enq_seg = enq_seg->next;
287 enq = enq_seg->trbs;
288 }
289 }
290 return 1;
291} 262}
292 263
293/* Ring the host controller doorbell after placing a command on the ring */ 264/* Ring the host controller doorbell after placing a command on the ring */
@@ -893,6 +864,43 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
893 xhci_dbg(xhci, "xHCI host controller is dead.\n"); 864 xhci_dbg(xhci, "xHCI host controller is dead.\n");
894} 865}
895 866
867
868static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
869 struct xhci_virt_device *dev,
870 struct xhci_ring *ep_ring,
871 unsigned int ep_index)
872{
873 union xhci_trb *dequeue_temp;
874 int num_trbs_free_temp;
875 bool revert = false;
876
877 num_trbs_free_temp = ep_ring->num_trbs_free;
878 dequeue_temp = ep_ring->dequeue;
879
880 while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) {
881 /* We have more usable TRBs */
882 ep_ring->num_trbs_free++;
883 ep_ring->dequeue++;
884 if (last_trb(xhci, ep_ring, ep_ring->deq_seg,
885 ep_ring->dequeue)) {
886 if (ep_ring->dequeue ==
887 dev->eps[ep_index].queued_deq_ptr)
888 break;
889 ep_ring->deq_seg = ep_ring->deq_seg->next;
890 ep_ring->dequeue = ep_ring->deq_seg->trbs;
891 }
892 if (ep_ring->dequeue == dequeue_temp) {
893 revert = true;
894 break;
895 }
896 }
897
898 if (revert) {
899 xhci_dbg(xhci, "Unable to find new dequeue pointer\n");
900 ep_ring->num_trbs_free = num_trbs_free_temp;
901 }
902}
903
896/* 904/*
897 * When we get a completion for a Set Transfer Ring Dequeue Pointer command, 905 * When we get a completion for a Set Transfer Ring Dequeue Pointer command,
898 * we need to clear the set deq pending flag in the endpoint ring state, so that 906 * we need to clear the set deq pending flag in the endpoint ring state, so that
@@ -974,8 +982,8 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
974 /* Update the ring's dequeue segment and dequeue pointer 982 /* Update the ring's dequeue segment and dequeue pointer
975 * to reflect the new position. 983 * to reflect the new position.
976 */ 984 */
977 ep_ring->deq_seg = dev->eps[ep_index].queued_deq_seg; 985 update_ring_for_set_deq_completion(xhci, dev,
978 ep_ring->dequeue = dev->eps[ep_index].queued_deq_ptr; 986 ep_ring, ep_index);
979 } else { 987 } else {
980 xhci_warn(xhci, "Mismatch between completed Set TR Deq " 988 xhci_warn(xhci, "Mismatch between completed Set TR Deq "
981 "Ptr command & xHCI internal state.\n"); 989 "Ptr command & xHCI internal state.\n");
@@ -3407,6 +3415,7 @@ cleanup:
3407 ep_ring->enqueue = urb_priv->td[0]->first_trb; 3415 ep_ring->enqueue = urb_priv->td[0]->first_trb;
3408 ep_ring->enq_seg = urb_priv->td[0]->start_seg; 3416 ep_ring->enq_seg = urb_priv->td[0]->start_seg;
3409 ep_ring->cycle_state = start_cycle; 3417 ep_ring->cycle_state = start_cycle;
3418 ep_ring->num_trbs_free = ep_ring->num_trbs_free_temp;
3410 usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); 3419 usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
3411 return ret; 3420 return ret;
3412} 3421}
@@ -3479,6 +3488,8 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
3479 urb->dev->speed == USB_SPEED_FULL) 3488 urb->dev->speed == USB_SPEED_FULL)
3480 urb->interval /= 8; 3489 urb->interval /= 8;
3481 } 3490 }
3491 ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free;
3492
3482 return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); 3493 return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
3483} 3494}
3484 3495
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 262400c10075..dec5b2dc298c 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -729,6 +729,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
729 ring->enq_seg = ring->deq_seg; 729 ring->enq_seg = ring->deq_seg;
730 ring->enqueue = ring->dequeue; 730 ring->enqueue = ring->dequeue;
731 731
732 ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
732 /* 733 /*
733 * Ring is now zeroed, so the HW should look for change of ownership 734 * Ring is now zeroed, so the HW should look for change of ownership
734 * when the cycle bit is set to 1. 735 * when the cycle bit is set to 1.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 2337a8e80b60..ea8fc237d158 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1278,6 +1278,8 @@ struct xhci_ring {
1278 u32 cycle_state; 1278 u32 cycle_state;
1279 unsigned int stream_id; 1279 unsigned int stream_id;
1280 unsigned int num_segs; 1280 unsigned int num_segs;
1281 unsigned int num_trbs_free;
1282 unsigned int num_trbs_free_temp;
1281 enum xhci_ring_type type; 1283 enum xhci_ring_type type;
1282 bool last_td_was_short; 1284 bool last_td_was_short;
1283}; 1285};