The 'cleanup' code at the bottom of xhci_queue_isoc_tx() can never be executed.

For 'i != 0' on an ISOC ring prepare_transfer can only fail if the endpoint
ring cannot be determined, but it was found only moments earlier (it could
be passed as a parameter).

The 'running_total' check is just checking that the code is correct
and can just be deleted now the code is working.

Remove the 'flip_cycle' parameter to td_to_noop() since it is no longer
ever set.

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

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 62049e5..ae5d32c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -617,12 +617,8 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
                        (unsigned long long) addr);
 }
 
-/* flip_cycle means flip the cycle bit of all but the first and last TRB.
- * (The last TRB actually points to the ring enqueue pointer, which is not part
- * of this TD.)  This is used to remove partially enqueued isoc TDs from a 
ring.
- */
 static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
-               struct xhci_td *cur_td, bool flip_cycle)
+               struct xhci_td *cur_td)
 {
        struct xhci_segment *cur_seg;
        union xhci_trb *cur_trb;
@@ -635,12 +631,6 @@ static void td_to_noop(struct xhci_hcd *xhci, struct 
xhci_ring *ep_ring,
                         * leave the pointers intact.
                         */
                        cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN);
-                       /* Flip the cycle bit (link TRBs can't be the first
-                        * or last TRB).
-                        */
-                       if (flip_cycle)
-                               cur_trb->generic.field[3] ^=
-                                       cpu_to_le32(TRB_CYCLE);
                        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                                        "Cancel (unchain) link TRB");
                        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -656,11 +646,6 @@ static void td_to_noop(struct xhci_hcd *xhci, struct 
xhci_ring *ep_ring,
                        cur_trb->generic.field[2] = 0;
                        /* Preserve only the cycle bit of this TRB */
                        cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE);
-                       /* Flip the cycle bit except on the first or last TRB */
-                       if (flip_cycle && cur_trb != cur_td->first_trb &&
-                                       cur_trb != cur_td->last_trb)
-                               cur_trb->generic.field[3] ^=
-                                       cpu_to_le32(TRB_CYCLE);
                        cur_trb->generic.field[3] |= cpu_to_le32(
                                TRB_TYPE(TRB_TR_NOOP));
                        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -834,7 +819,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, 
int slot_id,
                                        cur_td->urb->stream_id,
                                        cur_td, &deq_state);
                else
-                       td_to_noop(xhci, ep_ring, cur_td, false);
+                       td_to_noop(xhci, ep_ring, cur_td);
 remove_finished_td:
                /*
                 * The event handler won't see a completion for this TD anymore,
@@ -3834,11 +3819,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
 
                ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
                                urb->stream_id, trbs_per_td, urb, i, mem_flags);
-               if (ret < 0) {
-                       if (i == 0)
-                               return ret;
-                       goto cleanup;
-               }
+               if (ret < 0)
+                       /* This can only happen when for the first TD */
+                       return ret;
 
                td = urb_priv->td[i];
                for (j = 0; j < trbs_per_td; j++) {
@@ -3922,13 +3905,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
                        addr += trb_buff_len;
                        td_remain_len -= trb_buff_len;
                }
-
-               /* Check TD length */
-               if (running_total != td_len) {
-                       xhci_err(xhci, "ISOC TD length unmatch\n");
-                       ret = -EINVAL;
-                       goto cleanup;
-               }
        }
 
        if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) {
@@ -3939,28 +3915,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, 
gfp_t mem_flags,
 
        giveback_first_trb(xhci, slot_id, ep_index, ep_ring);
        return 0;
-cleanup:
-       /* Clean up a partially enqueued isoc transfer. */
-
-       for (i--; i >= 0; i--)
-               list_del_init(&urb_priv->td[i]->td_list);
-
-       /* Use the first TD as a temporary variable to turn the TDs we've queued
-        * into No-ops with a software-owned cycle bit. That way the hardware
-        * won't accidentally start executing bogus TDs when we partially
-        * overwrite them.  td->first_trb and td->start_seg are already set.
-        */
-       urb_priv->td[0]->last_trb = ep_ring->enqueue;
-       /* Every TRB except the first & last will have its cycle bit flipped. */
-       td_to_noop(xhci, ep_ring, urb_priv->td[0], true);
-
-       /* Reset the ring enqueue back to the first TRB and its cycle bit. */
-       ep_ring->enqueue = urb_priv->td[0]->first_trb;
-       ep_ring->enq_seg = urb_priv->td[0]->start_seg;
-       ep_ring->cycle_state = start_cycle;
-       ep_ring->num_trbs_free = ep_ring->num_trbs_free_temp;
-       usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
-       return ret;
 }
 
 /*
-- 
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