diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
commit | 6396fc3b3ff3f6b942992b653a62df11dcef9bea (patch) | |
tree | db3c7cbe833b43c653adc99f70941431c5ff7c4e /drivers/usb/host/xhci-mem.c | |
parent | 4785879e4d340e24e54f6de2ccfc42728b912808 (diff) | |
parent | 3d30701b58970425e1d45994d6cb82f828924fdd (diff) |
Merge branch 'master' into for-next
Conflicts:
fs/exofs/inode.c
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2eb658d26394..4e51343ddffc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -391,49 +391,6 @@ struct xhci_ring *xhci_stream_id_to_ring( | |||
391 | return ep->stream_info->stream_rings[stream_id]; | 391 | return ep->stream_info->stream_rings[stream_id]; |
392 | } | 392 | } |
393 | 393 | ||
394 | struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, | ||
395 | unsigned int slot_id, unsigned int ep_index, | ||
396 | unsigned int stream_id) | ||
397 | { | ||
398 | struct xhci_virt_ep *ep; | ||
399 | |||
400 | ep = &xhci->devs[slot_id]->eps[ep_index]; | ||
401 | /* Common case: no streams */ | ||
402 | if (!(ep->ep_state & EP_HAS_STREAMS)) | ||
403 | return ep->ring; | ||
404 | |||
405 | if (stream_id == 0) { | ||
406 | xhci_warn(xhci, | ||
407 | "WARN: Slot ID %u, ep index %u has streams, " | ||
408 | "but URB has no stream ID.\n", | ||
409 | slot_id, ep_index); | ||
410 | return NULL; | ||
411 | } | ||
412 | |||
413 | if (stream_id < ep->stream_info->num_streams) | ||
414 | return ep->stream_info->stream_rings[stream_id]; | ||
415 | |||
416 | xhci_warn(xhci, | ||
417 | "WARN: Slot ID %u, ep index %u has " | ||
418 | "stream IDs 1 to %u allocated, " | ||
419 | "but stream ID %u is requested.\n", | ||
420 | slot_id, ep_index, | ||
421 | ep->stream_info->num_streams - 1, | ||
422 | stream_id); | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
426 | /* Get the right ring for the given URB. | ||
427 | * If the endpoint supports streams, boundary check the URB's stream ID. | ||
428 | * If the endpoint doesn't support streams, return the singular endpoint ring. | ||
429 | */ | ||
430 | struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci, | ||
431 | struct urb *urb) | ||
432 | { | ||
433 | return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id, | ||
434 | xhci_get_endpoint_index(&urb->ep->desc), urb->stream_id); | ||
435 | } | ||
436 | |||
437 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING | 394 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING |
438 | static int xhci_test_radix_tree(struct xhci_hcd *xhci, | 395 | static int xhci_test_radix_tree(struct xhci_hcd *xhci, |
439 | unsigned int num_streams, | 396 | unsigned int num_streams, |
@@ -1112,8 +1069,18 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1112 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); | 1069 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); |
1113 | 1070 | ||
1114 | /* Set up the endpoint ring */ | 1071 | /* Set up the endpoint ring */ |
1115 | virt_dev->eps[ep_index].new_ring = | 1072 | /* |
1116 | xhci_ring_alloc(xhci, 1, true, mem_flags); | 1073 | * Isochronous endpoint ring needs bigger size because one isoc URB |
1074 | * carries multiple packets and it will insert multiple tds to the | ||
1075 | * ring. | ||
1076 | * This should be replaced with dynamic ring resizing in the future. | ||
1077 | */ | ||
1078 | if (usb_endpoint_xfer_isoc(&ep->desc)) | ||
1079 | virt_dev->eps[ep_index].new_ring = | ||
1080 | xhci_ring_alloc(xhci, 8, true, mem_flags); | ||
1081 | else | ||
1082 | virt_dev->eps[ep_index].new_ring = | ||
1083 | xhci_ring_alloc(xhci, 1, true, mem_flags); | ||
1117 | if (!virt_dev->eps[ep_index].new_ring) { | 1084 | if (!virt_dev->eps[ep_index].new_ring) { |
1118 | /* Attempt to use the ring cache */ | 1085 | /* Attempt to use the ring cache */ |
1119 | if (virt_dev->num_rings_cached == 0) | 1086 | if (virt_dev->num_rings_cached == 0) |
@@ -1124,6 +1091,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1124 | virt_dev->num_rings_cached--; | 1091 | virt_dev->num_rings_cached--; |
1125 | xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); | 1092 | xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); |
1126 | } | 1093 | } |
1094 | virt_dev->eps[ep_index].skip = false; | ||
1127 | ep_ring = virt_dev->eps[ep_index].new_ring; | 1095 | ep_ring = virt_dev->eps[ep_index].new_ring; |
1128 | ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; | 1096 | ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; |
1129 | 1097 | ||
@@ -1389,6 +1357,22 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | |||
1389 | return command; | 1357 | return command; |
1390 | } | 1358 | } |
1391 | 1359 | ||
1360 | void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) | ||
1361 | { | ||
1362 | int last; | ||
1363 | |||
1364 | if (!urb_priv) | ||
1365 | return; | ||
1366 | |||
1367 | last = urb_priv->length - 1; | ||
1368 | if (last >= 0) { | ||
1369 | int i; | ||
1370 | for (i = 0; i <= last; i++) | ||
1371 | kfree(urb_priv->td[i]); | ||
1372 | } | ||
1373 | kfree(urb_priv); | ||
1374 | } | ||
1375 | |||
1392 | void xhci_free_command(struct xhci_hcd *xhci, | 1376 | void xhci_free_command(struct xhci_hcd *xhci, |
1393 | struct xhci_command *command) | 1377 | struct xhci_command *command) |
1394 | { | 1378 | { |
@@ -1588,7 +1572,7 @@ static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) | |||
1588 | unsigned int num_tests; | 1572 | unsigned int num_tests; |
1589 | int i, ret; | 1573 | int i, ret; |
1590 | 1574 | ||
1591 | num_tests = sizeof(simple_test_vector) / sizeof(simple_test_vector[0]); | 1575 | num_tests = ARRAY_SIZE(simple_test_vector); |
1592 | for (i = 0; i < num_tests; i++) { | 1576 | for (i = 0; i < num_tests; i++) { |
1593 | ret = xhci_test_trb_in_td(xhci, | 1577 | ret = xhci_test_trb_in_td(xhci, |
1594 | xhci->event_ring->first_seg, | 1578 | xhci->event_ring->first_seg, |
@@ -1601,7 +1585,7 @@ static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) | |||
1601 | return ret; | 1585 | return ret; |
1602 | } | 1586 | } |
1603 | 1587 | ||
1604 | num_tests = sizeof(complex_test_vector) / sizeof(complex_test_vector[0]); | 1588 | num_tests = ARRAY_SIZE(complex_test_vector); |
1605 | for (i = 0; i < num_tests; i++) { | 1589 | for (i = 0; i < num_tests; i++) { |
1606 | ret = xhci_test_trb_in_td(xhci, | 1590 | ret = xhci_test_trb_in_td(xhci, |
1607 | complex_test_vector[i].input_seg, | 1591 | complex_test_vector[i].input_seg, |
@@ -1617,6 +1601,29 @@ static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) | |||
1617 | return 0; | 1601 | return 0; |
1618 | } | 1602 | } |
1619 | 1603 | ||
1604 | static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | ||
1605 | { | ||
1606 | u64 temp; | ||
1607 | dma_addr_t deq; | ||
1608 | |||
1609 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, | ||
1610 | xhci->event_ring->dequeue); | ||
1611 | if (deq == 0 && !in_interrupt()) | ||
1612 | xhci_warn(xhci, "WARN something wrong with SW event ring " | ||
1613 | "dequeue ptr.\n"); | ||
1614 | /* Update HC event ring dequeue pointer */ | ||
1615 | temp = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); | ||
1616 | temp &= ERST_PTR_MASK; | ||
1617 | /* Don't clear the EHB bit (which is RW1C) because | ||
1618 | * there might be more events to service. | ||
1619 | */ | ||
1620 | temp &= ~ERST_EHB; | ||
1621 | xhci_dbg(xhci, "// Write event ring dequeue pointer, " | ||
1622 | "preserving EHB bit\n"); | ||
1623 | xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, | ||
1624 | &xhci->ir_set->erst_dequeue); | ||
1625 | } | ||
1626 | |||
1620 | 1627 | ||
1621 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | 1628 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) |
1622 | { | 1629 | { |