diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 76 |
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 | |||
2673 | static 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 | |||
2658 | static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | 2687 | static 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), |