The only difference between these two routines is that the latter
handles a scatterlist of more than one entry.  Fake a single entry
scatterlist for the non-sg case, and delete the duplicate code.

Signed-off-by: Dan Williams <dan.j.willi...@intel.com>
---
 drivers/usb/host/xhci-ring.c |  158 +++++-------------------------------------
 1 files changed, 19 insertions(+), 139 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 3a9ed6543dfe..ed42704f68ad 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3044,17 +3044,15 @@ static int prepare_transfer(struct xhci_hcd *xhci,
        return prepare_td(ep_ring, urb, td_index);
 }
 
-static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb 
*urb)
+static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci,
+               struct urb *urb, struct scatterlist *sgl, int num_sgs)
 {
-       int num_sgs, num_trbs, running_total, temp, i;
+       int num_trbs, running_total, temp, i;
        struct scatterlist *sg;
 
-       sg = NULL;
-       num_sgs = urb->num_mapped_sgs;
        temp = urb->transfer_buffer_length;
-
        num_trbs = 0;
-       for_each_sg(urb->sg, sg, num_sgs, i) {
+       for_each_sg(sgl, sg, num_sgs, i) {
                unsigned int len = sg_dma_len(sg);
 
                /* Scatter gather list entries may cross 64KB boundaries */
@@ -3198,15 +3196,15 @@ static u32 xhci_v1_0_td_remainder(int running_total, 
int trb_buff_len,
 }
 
 static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
-               struct urb *urb, int slot_id, unsigned int ep_index)
+               struct urb *urb, struct scatterlist *sgl, int num_sgs,
+               int slot_id, unsigned int ep_index)
 {
        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;
+       struct scatterlist *sg = sgl;
        unsigned int total_packet_count;
        bool first_trb;
        u64 addr;
@@ -3218,8 +3216,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
        if (!ep_ring)
                return -EINVAL;
 
-       num_trbs = count_sg_trbs_needed(xhci, urb);
-       num_sgs = urb->num_mapped_sgs;
+       num_trbs = count_sg_trbs_needed(xhci, urb, sgl, num_sgs);
        total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
                        usb_endpoint_maxp(&urb->ep->desc));
 
@@ -3250,7 +3247,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
         *    the amount of memory allocated for this scatter-gather list.
         * 3. TRBs buffers can't cross 64KB boundaries.
         */
-       sg = urb->sg;
        addr = (u64) sg_dma_address(sg);
        this_sg_len = sg_dma_len(sg);
        trb_buff_len = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1));
@@ -3349,140 +3345,24 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
        return 0;
 }
 
-/* This is very similar to what ehci-q.c qtd_fill() does */
 int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                struct urb *urb, int slot_id, unsigned int ep_index)
 {
-       struct xhci_ring *ep_ring;
-       struct urb_priv *urb_priv;
-       struct xhci_td *td;
-       int num_trbs;
-       bool first_trb;
-       bool more_trbs_coming;
-       int start_cycle;
-       u32 field, length_field;
-       union xhci_trb *start_trb;
-       int running_total, trb_buff_len, ret;
-       unsigned int total_packet_count;
-       u64 addr;
-
        if (urb->num_sgs)
-               return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, 
ep_index);
+               return queue_bulk_sg_tx(xhci, mem_flags, urb, urb->sg,
+                               urb->num_mapped_sgs, slot_id, ep_index);
+       else {
+               struct scatterlist scatter, *sg = &scatter;
 
-       ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
-       if (!ep_ring)
-               return -EINVAL;
-
-       num_trbs = 0;
-       /* How much data is (potentially) left before the 64KB boundary? */
-       running_total = TRB_MAX_BUFF_SIZE -
-               (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1));
-       running_total &= TRB_MAX_BUFF_SIZE - 1;
+               sg_init_table(sg, 1);
+               sg_set_buf(sg, urb->transfer_buffer,
+                               urb->transfer_buffer_length);
+               sg->dma_address = urb->transfer_dma;
+               sg_dma_len(sg) = sg->length;
 
-       /* If there's some data on this 64KB chunk, or we have to send a
-        * zero-length transfer, we need at least one TRB
-        */
-       if (running_total != 0 || urb->transfer_buffer_length == 0)
-               num_trbs++;
-       /* How many more 64KB chunks to transfer, how many more TRBs? */
-       while (running_total < urb->transfer_buffer_length) {
-               num_trbs++;
-               running_total += TRB_MAX_BUFF_SIZE;
+               return queue_bulk_sg_tx(xhci, mem_flags, urb, sg, 1, slot_id,
+                               ep_index);
        }
-       /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
-
-       ret = prepare_transfer(xhci, xhci->devs[slot_id],
-                       ep_index, urb->stream_id,
-                       num_trbs, urb, 0, mem_flags);
-       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)
-        * until we've finished creating all the other TRBs.  The ring's cycle
-        * state may change as we enqueue the other TRBs, so save it too.
-        */
-       start_trb = xhci_ring_enqueue(ep_ring);
-       start_cycle = ep_ring->cycle_state;
-
-       running_total = 0;
-       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;
-       trb_buff_len = TRB_MAX_BUFF_SIZE -
-               (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1));
-       if (trb_buff_len > urb->transfer_buffer_length)
-               trb_buff_len = urb->transfer_buffer_length;
-
-       first_trb = true;
-
-       /* Queue the first TRB, even if it's zero-length */
-       do {
-               u32 remainder = 0;
-               field = 0;
-
-               /* Don't change the cycle bit of the first TRB until later */
-               if (first_trb) {
-                       first_trb = false;
-                       if (start_cycle == 0)
-                               field |= 0x1;
-               } else
-                       field |= ep_ring->cycle_state;
-
-               /* 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) {
-                       field |= TRB_CHAIN;
-               } else {
-                       /* FIXME - add check for ZERO_PACKET flag before this */
-                       td->last_trb = xhci_ring_enqueue(ep_ring);
-                       field |= TRB_IOC;
-               }
-
-               /* Only set interrupt on short packet for IN endpoints */
-               if (usb_urb_dir_in(urb))
-                       field |= TRB_ISP;
-
-               /* Set the TRB length, TD size, and interrupter fields. */
-               if (xhci->hci_version < 0x100) {
-                       remainder = xhci_td_remainder(
-                                       urb->transfer_buffer_length -
-                                       running_total);
-               } else {
-                       remainder = xhci_v1_0_td_remainder(running_total,
-                                       trb_buff_len, total_packet_count, urb,
-                                       num_trbs - 1);
-               }
-               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(ep_ring, more_trbs_coming, lower_32_bits(addr),
-                               upper_32_bits(addr), length_field,
-                               field | TRB_TYPE(TRB_NORMAL));
-               --num_trbs;
-               running_total += trb_buff_len;
-
-               /* Calculate length for next transfer */
-               addr += trb_buff_len;
-               trb_buff_len = urb->transfer_buffer_length - running_total;
-               if (trb_buff_len > TRB_MAX_BUFF_SIZE)
-                       trb_buff_len = TRB_MAX_BUFF_SIZE;
-       } while (running_total < urb->transfer_buffer_length);
-
-       check_trb_math(urb, num_trbs, running_total);
-       giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
-                       start_cycle, start_trb);
-       return 0;
 }
 
 /* Caller must have locked xhci->lock */

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

Reply via email to