[PATCH v3 2/9] xhci: Minor cleanups to queue_bulk_sg_tx()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- Use a separate 'ret' variable for the result of prepare_transfer().
- No need to assign 'urb_priv' and 'td' until the last fragment.
- Add 'len_left' to count the bytes remaining, use instead of
  'urb->transfer_buffer_length - running_total' and to check for the
  last fragment (instead of num_trbs - which is now only used for
  the call to prepare_transfer().
- No need to pass 'more_trbs_coming' to queue_trb(), it is implied
  if TRB_CHAIN is set.
- Finish the loop when we failed to set TRB_CHAIN.

Signed-off-by: David Laight <david.laight@xxxxxxxxxx>
---
 drivers/usb/host/xhci-ring.c | 48 ++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d84b183..b60932b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3260,14 +3260,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	struct xhci_ring *ep_ring;
 	unsigned int num_trbs;
 	struct urb_priv *urb_priv;
-	struct xhci_td *td;
 	struct scatterlist *sg;
 	int num_sgs;
 	int trb_buff_len, this_sg_len, running_total;
+	int len_left;
 	unsigned int total_packet_count;
 	bool first_trb;
 	u64 addr;
-	bool more_trbs_coming;
+	int ret;
 
 	struct xhci_generic_trb *start_trb;
 	int start_cycle;
@@ -3281,14 +3281,12 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	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],
+	ret = prepare_transfer(xhci, xhci->devs[slot_id],
 			ep_index, urb->stream_id,
 			num_trbs, urb, 0, mem_flags);
-	if (trb_buff_len < 0)
-		return trb_buff_len;
+	if (ret < 0)
+		return ret;
 
-	urb_priv = urb->hcpriv;
-	td = urb_priv->td[0];
 
 	/*
 	 * Don't give the first TRB to the hardware (by toggling the cycle bit)
@@ -3299,6 +3297,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	start_cycle = ep_ring->cycle_state;
 
 	running_total = 0;
+	len_left = urb->transfer_buffer_length;
 	/*
 	 * How much data is in the first TRB?
 	 *
@@ -3318,7 +3317,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 	first_trb = true;
 	/* Queue the first TRB, even if it's zero-length */
-	do {
+	for (;;) {
 		u32 field = 0;
 		u32 length_field = 0;
 		u32 remainder = 0;
@@ -3334,11 +3333,12 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		/* Chain all the TRBs together; clear the chain bit in the last
 		 * TRB to indicate it's the last TRB in the chain.
 		 */
-		if (num_trbs > 1) {
+		if (trb_buff_len != len_left) {
 			field |= TRB_CHAIN;
 		} else {
 			/* FIXME - add check for ZERO_PACKET flag before this */
-			td->last_trb = ep_ring->enqueue;
+			urb_priv = urb->hcpriv;
+			urb_priv->td[0]->last_trb = ep_ring->enqueue;
 			field |= TRB_IOC;
 		}
 
@@ -3348,29 +3348,28 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 		/* Set the TRB length, TD size, and interrupter fields. */
 		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
-					urb->transfer_buffer_length -
-					running_total);
+			remainder = xhci_td_remainder(len_left);
 		} else {
 			remainder = xhci_v1_0_td_remainder(running_total,
 					trb_buff_len, total_packet_count, urb,
-					num_trbs - 1);
+					trb_buff_len != len_left);
 		}
 		length_field = TRB_LEN(trb_buff_len) |
 			remainder |
 			TRB_INTR_TARGET(0);
 
-		if (num_trbs > 1)
-			more_trbs_coming = true;
-		else
-			more_trbs_coming = false;
-		queue_trb(xhci, ep_ring, more_trbs_coming,
+		queue_trb(xhci, ep_ring, false,
 				lower_32_bits(addr),
 				upper_32_bits(addr),
 				length_field,
 				field | TRB_TYPE(TRB_NORMAL));
-		--num_trbs;
+
+		/* If we didn't set the chain bit, we must have finished */
+		if (!(field & TRB_CHAIN))
+			break;
+
 		running_total += trb_buff_len;
+		len_left -= trb_buff_len;
 
 		/* Calculate length for next transfer --
 		 * Are we done queueing all the TRBs for this sg entry?
@@ -3378,8 +3377,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		this_sg_len -= trb_buff_len;
 		if (this_sg_len == 0) {
 			--num_sgs;
-			if (num_sgs == 0)
-				break;
 			sg = sg_next(sg);
 			addr = (u64) sg_dma_address(sg);
 			this_sg_len = sg_dma_len(sg);
@@ -3390,10 +3387,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		trb_buff_len = TRB_MAX_BUFF_SIZE -
 			(addr & (TRB_MAX_BUFF_SIZE - 1));
 		trb_buff_len = min_t(int, trb_buff_len, this_sg_len);
-		if (running_total + trb_buff_len > urb->transfer_buffer_length)
-			trb_buff_len =
-				urb->transfer_buffer_length - running_total;
-	} while (running_total < urb->transfer_buffer_length);
+		if (trb_buff_len > len_left)
+			trb_buff_len = len_left;
+	}
 
 	giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
 			start_cycle, start_trb);
-- 
1.8.1.2



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux