Modify the code in queue_bulk_sg_tx() to support non-sg transfers.
Rename it xhci_queue_bulk_tx() and delete the old xhci_queue_bulk_tx().

Signed-off-by: David Laight <david.lai...@aculab.com>
---
 drivers/usb/host/xhci-ring.c | 159 ++++---------------------------------------
 1 file changed, 15 insertions(+), 144 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 1324bb0..52ea564 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3265,7 +3265,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int 
trb_buff_len,
        return (total_packet_count - packets_transferred) << 17;
 }
 
-static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+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;
@@ -3286,7 +3286,20 @@ 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(ep_ring, urb);
+       if (urb->num_sgs) {
+               sg = urb->sg;
+               addr = (u64) sg_dma_address(sg);
+               this_sg_len = sg_dma_len(sg);
+               num_trbs = count_sg_trbs_needed(ep_ring, urb);
+       } else {
+               sg = NULL;
+               addr = urb->transfer_dma;
+               this_sg_len = urb->transfer_buffer_length;
+               num_trbs = DIV_ROUND_UP((addr & (TRB_MAX_BUFF_SIZE - 1)) +
+                               this_sg_len, TRB_MAX_BUFF_SIZE);
+               if (num_trbs == 0)
+                       num_trbs = 1;
+       }
 
        /*
         * For v1.0 endpoints we need to calculate the number of packets
@@ -3341,10 +3354,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t 
mem_flags,
 
        len_left = urb->transfer_buffer_length;
 
-       sg = urb->sg;
-       addr = (u64) sg_dma_address(sg);
-       this_sg_len = sg_dma_len(sg);
-
        /* Queue the first TRB, even if it's zero-length */
        for (;;) {
                u32 length_field = 0;
@@ -3420,144 +3429,6 @@ next_frag:
        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;
-       struct xhci_generic_trb *start_trb;
-       bool first_trb;
-       bool more_trbs_coming;
-       int start_cycle;
-       u32 field, length_field;
-
-       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);
-
-       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;
-
-       /* 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;
-       }
-       /* 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 = &ep_ring->enqueue->generic;
-       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 = ep_ring->enqueue;
-                       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(xhci, 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);
-
-       giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
-                       start_cycle, start_trb);
-       return 0;
-}
-
 /* Caller must have locked xhci->lock */
 int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                struct urb *urb, int slot_id, unsigned int ep_index)
-- 
1.8.1.2



--
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