aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2011-04-01 17:01:30 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-05-02 19:42:55 -0400
commit4da6e6f247a2601ab9f1e63424e4d944ed4124f3 (patch)
treec337dbf51114b7aafb122a16c35807e661b4036b /drivers/usb/host
parentaf8b9e636065ba1701c4215a8dc4f7a1d69d934b (diff)
xhci 1.0: Update TD size field format.
The xHCI 1.0 specification changes the format of the TD size field in Normal and Isochronous TRBs. The field in control TRBs is still set to reserved zero. Instead of representing the number of bytes left to transfer in the TD (including the current TRB's buffer), it now represents the number of packets left to transfer (*not* including this TRB). See section 4.11.2.4 of the xHCI 1.0 specification for details. The math is basically copied straight from there. Create a new function, xhci_v1_0_td_remainder(), that should be called for all xHCI 1.0 host controllers. The field location and maximum value is still the same, so reuse the old function, xhci_td_remainder(), to handle the bit shifting. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c76
1 files changed, 70 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 766f6a615b2a..27d690d889af 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2655,6 +2655,35 @@ static u32 xhci_td_remainder(unsigned int remainder)
2655 return (remainder >> 10) << 17; 2655 return (remainder >> 10) << 17;
2656} 2656}
2657 2657
2658/*
2659 * For xHCI 1.0 host controllers, TD size is the number of packets remaining in
2660 * the TD (*not* including this TRB).
2661 *
2662 * Total TD packet count = total_packet_count =
2663 * roundup(TD size in bytes / wMaxPacketSize)
2664 *
2665 * Packets transferred up to and including this TRB = packets_transferred =
2666 * rounddown(total bytes transferred including this TRB / wMaxPacketSize)
2667 *
2668 * TD size = total_packet_count - packets_transferred
2669 *
2670 * It must fit in bits 21:17, so it can't be bigger than 31.
2671 */
2672
2673static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
2674 unsigned int total_packet_count, struct urb *urb)
2675{
2676 int packets_transferred;
2677
2678 /* All the TRB queueing functions don't count the current TRB in
2679 * running_total.
2680 */
2681 packets_transferred = (running_total + trb_buff_len) /
2682 le16_to_cpu(urb->ep->desc.wMaxPacketSize);
2683
2684 return xhci_td_remainder(total_packet_count - packets_transferred);
2685}
2686
2658static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, 2687static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2659 struct urb *urb, int slot_id, unsigned int ep_index) 2688 struct urb *urb, int slot_id, unsigned int ep_index)
2660{ 2689{
@@ -2665,6 +2694,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2665 struct scatterlist *sg; 2694 struct scatterlist *sg;
2666 int num_sgs; 2695 int num_sgs;
2667 int trb_buff_len, this_sg_len, running_total; 2696 int trb_buff_len, this_sg_len, running_total;
2697 unsigned int total_packet_count;
2668 bool first_trb; 2698 bool first_trb;
2669 u64 addr; 2699 u64 addr;
2670 bool more_trbs_coming; 2700 bool more_trbs_coming;
@@ -2678,6 +2708,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2678 2708
2679 num_trbs = count_sg_trbs_needed(xhci, urb); 2709 num_trbs = count_sg_trbs_needed(xhci, urb);
2680 num_sgs = urb->num_sgs; 2710 num_sgs = urb->num_sgs;
2711 total_packet_count = roundup(urb->transfer_buffer_length,
2712 le16_to_cpu(urb->ep->desc.wMaxPacketSize));
2681 2713
2682 trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id], 2714 trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
2683 ep_index, urb->stream_id, 2715 ep_index, urb->stream_id,
@@ -2758,11 +2790,20 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2758 (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), 2790 (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1),
2759 (unsigned int) addr + trb_buff_len); 2791 (unsigned int) addr + trb_buff_len);
2760 } 2792 }
2761 remainder = xhci_td_remainder(urb->transfer_buffer_length - 2793
2762 running_total) ; 2794 /* Set the TRB length, TD size, and interrupter fields. */
2795 if (xhci->hci_version < 0x100) {
2796 remainder = xhci_td_remainder(
2797 urb->transfer_buffer_length -
2798 running_total);
2799 } else {
2800 remainder = xhci_v1_0_td_remainder(running_total,
2801 trb_buff_len, total_packet_count, urb);
2802 }
2763 length_field = TRB_LEN(trb_buff_len) | 2803 length_field = TRB_LEN(trb_buff_len) |
2764 remainder | 2804 remainder |
2765 TRB_INTR_TARGET(0); 2805 TRB_INTR_TARGET(0);
2806
2766 if (num_trbs > 1) 2807 if (num_trbs > 1)
2767 more_trbs_coming = true; 2808 more_trbs_coming = true;
2768 else 2809 else
@@ -2819,6 +2860,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2819 u32 field, length_field; 2860 u32 field, length_field;
2820 2861
2821 int running_total, trb_buff_len, ret; 2862 int running_total, trb_buff_len, ret;
2863 unsigned int total_packet_count;
2822 u64 addr; 2864 u64 addr;
2823 2865
2824 if (urb->num_sgs) 2866 if (urb->num_sgs)
@@ -2873,6 +2915,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2873 start_cycle = ep_ring->cycle_state; 2915 start_cycle = ep_ring->cycle_state;
2874 2916
2875 running_total = 0; 2917 running_total = 0;
2918 total_packet_count = roundup(urb->transfer_buffer_length,
2919 le16_to_cpu(urb->ep->desc.wMaxPacketSize));
2876 /* How much data is in the first TRB? */ 2920 /* How much data is in the first TRB? */
2877 addr = (u64) urb->transfer_dma; 2921 addr = (u64) urb->transfer_dma;
2878 trb_buff_len = TRB_MAX_BUFF_SIZE - 2922 trb_buff_len = TRB_MAX_BUFF_SIZE -
@@ -2910,11 +2954,19 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
2910 if (usb_urb_dir_in(urb)) 2954 if (usb_urb_dir_in(urb))
2911 field |= TRB_ISP; 2955 field |= TRB_ISP;
2912 2956
2913 remainder = xhci_td_remainder(urb->transfer_buffer_length - 2957 /* Set the TRB length, TD size, and interrupter fields. */
2914 running_total); 2958 if (xhci->hci_version < 0x100) {
2959 remainder = xhci_td_remainder(
2960 urb->transfer_buffer_length -
2961 running_total);
2962 } else {
2963 remainder = xhci_v1_0_td_remainder(running_total,
2964 trb_buff_len, total_packet_count, urb);
2965 }
2915 length_field = TRB_LEN(trb_buff_len) | 2966 length_field = TRB_LEN(trb_buff_len) |
2916 remainder | 2967 remainder |
2917 TRB_INTR_TARGET(0); 2968 TRB_INTR_TARGET(0);
2969
2918 if (num_trbs > 1) 2970 if (num_trbs > 1)
2919 more_trbs_coming = true; 2971 more_trbs_coming = true;
2920 else 2972 else
@@ -3111,12 +3163,15 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
3111 3163
3112 /* Queue the first TRB, even if it's zero-length */ 3164 /* Queue the first TRB, even if it's zero-length */
3113 for (i = 0; i < num_tds; i++) { 3165 for (i = 0; i < num_tds; i++) {
3114 first_trb = true; 3166 unsigned int total_packet_count;
3115 3167
3168 first_trb = true;
3116 running_total = 0; 3169 running_total = 0;
3117 addr = start_addr + urb->iso_frame_desc[i].offset; 3170 addr = start_addr + urb->iso_frame_desc[i].offset;
3118 td_len = urb->iso_frame_desc[i].length; 3171 td_len = urb->iso_frame_desc[i].length;
3119 td_remain_len = td_len; 3172 td_remain_len = td_len;
3173 total_packet_count = roundup(td_len,
3174 le16_to_cpu(urb->ep->desc.wMaxPacketSize));
3120 3175
3121 trbs_per_td = count_isoc_trbs_needed(xhci, urb, i); 3176 trbs_per_td = count_isoc_trbs_needed(xhci, urb, i);
3122 3177
@@ -3172,10 +3227,19 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
3172 if (trb_buff_len > td_remain_len) 3227 if (trb_buff_len > td_remain_len)
3173 trb_buff_len = td_remain_len; 3228 trb_buff_len = td_remain_len;
3174 3229
3175 remainder = xhci_td_remainder(td_len - running_total); 3230 /* Set the TRB length, TD size, & interrupter fields. */
3231 if (xhci->hci_version < 0x100) {
3232 remainder = xhci_td_remainder(
3233 td_len - running_total);
3234 } else {
3235 remainder = xhci_v1_0_td_remainder(
3236 running_total, trb_buff_len,
3237 total_packet_count, urb);
3238 }
3176 length_field = TRB_LEN(trb_buff_len) | 3239 length_field = TRB_LEN(trb_buff_len) |
3177 remainder | 3240 remainder |
3178 TRB_INTR_TARGET(0); 3241 TRB_INTR_TARGET(0);
3242
3179 queue_trb(xhci, ep_ring, false, more_trbs_coming, 3243 queue_trb(xhci, ep_ring, false, more_trbs_coming,
3180 lower_32_bits(addr), 3244 lower_32_bits(addr),
3181 upper_32_bits(addr), 3245 upper_32_bits(addr),