Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 338657
b: refs/heads/master
c: 4525c0a
h: refs/heads/master
i:
  338655: 5330b61
v: v3
  • Loading branch information
Sarah Sharp committed Nov 12, 2012
1 parent 9a83735 commit b0a6c87
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 392a07ae3316f2b90b39ce41e66d6f6b5c95de90
refs/heads/master: 4525c0a10dff7ad3669763c28016c7daffc3900e
32 changes: 19 additions & 13 deletions trunk/drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3071,27 +3071,28 @@ static u32 xhci_td_remainder(unsigned int remainder)
}

/*
* For xHCI 1.0 host controllers, TD size is the number of packets remaining in
* the TD (*not* including this TRB).
* For xHCI 1.0 host controllers, TD size is the number of max packet sized
* packets remaining in the TD (*not* including this TRB).
*
* Total TD packet count = total_packet_count =
* roundup(TD size in bytes / wMaxPacketSize)
* DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
*
* Packets transferred up to and including this TRB = packets_transferred =
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
*
* TD size = total_packet_count - packets_transferred
*
* It must fit in bits 21:17, so it can't be bigger than 31.
* The last TRB in a TD must have the TD size set to zero.
*/

static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
unsigned int total_packet_count, struct urb *urb)
unsigned int total_packet_count, struct urb *urb,
unsigned int num_trbs_left)
{
int packets_transferred;

/* One TRB with a zero-length data packet. */
if (running_total == 0 && trb_buff_len == 0)
if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
return 0;

/* All the TRB queueing functions don't count the current TRB in
Expand All @@ -3100,7 +3101,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc);

return xhci_td_remainder(total_packet_count - packets_transferred);
if ((total_packet_count - packets_transferred) > 31)
return 31 << 17;
return (total_packet_count - packets_transferred) << 17;
}

static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
Expand All @@ -3127,7 +3130,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,

num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_mapped_sgs;
total_packet_count = roundup(urb->transfer_buffer_length,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));

trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
Expand Down Expand Up @@ -3210,7 +3213,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
trb_buff_len, total_packet_count, urb);
trb_buff_len, total_packet_count, urb,
num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
Expand Down Expand Up @@ -3318,7 +3322,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
start_cycle = ep_ring->cycle_state;

running_total = 0;
total_packet_count = roundup(urb->transfer_buffer_length,
total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
/* How much data is in the first TRB? */
addr = (u64) urb->transfer_dma;
Expand Down Expand Up @@ -3364,7 +3368,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
trb_buff_len, total_packet_count, urb);
trb_buff_len, total_packet_count, urb,
num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
Expand Down Expand Up @@ -3627,7 +3632,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len;
total_packet_count = roundup(td_len,
total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
Expand Down Expand Up @@ -3706,7 +3711,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} else {
remainder = xhci_v1_0_td_remainder(
running_total, trb_buff_len,
total_packet_count, urb);
total_packet_count, urb,
(trbs_per_td - j - 1));
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
Expand Down

0 comments on commit b0a6c87

Please sign in to comment.