]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/host/xhci-ring.c
usb: xhci: kill a conditional when toggling cycle
[~andy/linux] / drivers / usb / host / xhci-ring.c
index 3e80532847522fcbc8926babc50733610de57b15..1e2f3f4958436fb120b81d41632ad7e7c76fb5b5 100644 (file)
@@ -178,7 +178,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
                        if (ring->type == TYPE_EVENT &&
                                        last_trb_on_last_seg(xhci, ring,
                                                ring->deq_seg, ring->dequeue)) {
-                               ring->cycle_state = (ring->cycle_state ? 0 : 1);
+                               ring->cycle_state ^= 1;
                        }
                        ring->deq_seg = ring->deq_seg->next;
                        ring->dequeue = ring->deq_seg->trbs;
@@ -765,10 +765,9 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
  *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the chain
  *     bit cleared) so that the HW will skip over them.
  */
-static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
+static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
                union xhci_trb *trb, struct xhci_event_cmd *event)
 {
-       unsigned int slot_id;
        unsigned int ep_index;
        struct xhci_virt_device *virt_dev;
        struct xhci_ring *ep_ring;
@@ -779,10 +778,7 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
 
        struct xhci_dequeue_state deq_state;
 
-       if (unlikely(TRB_TO_SUSPEND_PORT(
-                            le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])))) {
-               slot_id = TRB_TO_SLOT_ID(
-                       le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]));
+       if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) {
                virt_dev = xhci->devs[slot_id];
                if (virt_dev)
                        handle_cmd_in_cmd_wait_list(xhci, virt_dev,
@@ -795,7 +791,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci,
        }
 
        memset(&deq_state, 0, sizeof(deq_state));
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        ep = &xhci->devs[slot_id]->eps[ep_index];
 
@@ -1077,10 +1072,9 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
  * endpoint doorbell to restart the ring, but only if there aren't more
  * cancellations pending.
  */
-static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
-               struct xhci_event_cmd *event, union xhci_trb *trb)
+static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
+               union xhci_trb *trb, u32 cmd_comp_code)
 {
-       unsigned int slot_id;
        unsigned int ep_index;
        unsigned int stream_id;
        struct xhci_ring *ep_ring;
@@ -1088,7 +1082,6 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
        struct xhci_ep_ctx *ep_ctx;
        struct xhci_slot_ctx *slot_ctx;
 
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
        dev = xhci->devs[slot_id];
@@ -1106,11 +1099,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
        ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
        slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
 
-       if (GET_COMP_CODE(le32_to_cpu(event->status)) != COMP_SUCCESS) {
+       if (cmd_comp_code != COMP_SUCCESS) {
                unsigned int ep_state;
                unsigned int slot_state;
 
-               switch (GET_COMP_CODE(le32_to_cpu(event->status))) {
+               switch (cmd_comp_code) {
                case COMP_TRB_ERR:
                        xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because "
                                        "of stream ID configuration\n");
@@ -1133,7 +1126,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
                default:
                        xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown "
                                        "completion code of %u.\n",
-                                 GET_COMP_CODE(le32_to_cpu(event->status)));
+                                 cmd_comp_code);
                        break;
                }
                /* OK what do we do now?  The endpoint state is hosed, and we
@@ -1170,20 +1163,17 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci,
        ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
-static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci,
-               struct xhci_event_cmd *event, union xhci_trb *trb)
+static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
+               union xhci_trb *trb, u32 cmd_comp_code)
 {
-       int slot_id;
        unsigned int ep_index;
 
-       slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));
        ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
        /* This command will only fail if the endpoint wasn't halted,
         * but we don't care.
         */
        xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
-               "Ignoring reset ep completion code of %u",
-                GET_COMP_CODE(le32_to_cpu(event->status)));
+               "Ignoring reset ep completion code of %u", cmd_comp_code);
 
        /* HW with the reset endpoint quirk needs to have a configure endpoint
         * command complete before the endpoint can be used.  Queue that here
@@ -1519,10 +1509,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
        int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
        u64 cmd_dma;
        dma_addr_t cmd_dequeue_dma;
+       u32 cmd_comp_code;
+       union xhci_trb *cmd_trb;
+       u32 cmd_type;
 
        cmd_dma = le64_to_cpu(event->cmd_trb);
+       cmd_trb = xhci->cmd_ring->dequeue;
        cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
-                       xhci->cmd_ring->dequeue);
+                       cmd_trb);
        /* Is the command ring deq ptr out of sync with the deq seg ptr? */
        if (cmd_dequeue_dma == 0) {
                xhci->error_bitmask |= 1 << 4;
@@ -1534,19 +1528,17 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
                return;
        }
 
-       trace_xhci_cmd_completion(&xhci->cmd_ring->dequeue->generic,
-                                       (struct xhci_generic_trb *) event);
+       trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
 
-       if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) ||
-               (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) {
+       cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
+       if (cmd_comp_code == COMP_CMD_ABORT || cmd_comp_code == COMP_CMD_STOP) {
                /* If the return value is 0, we think the trb pointed by
                 * command ring dequeue pointer is a good trb. The good
                 * trb means we don't want to cancel the trb, but it have
                 * been stopped by host. So we should handle it normally.
                 * Otherwise, driver should invoke inc_deq() and return.
                 */
-               if (handle_stopped_cmd_ring(xhci,
-                               GET_COMP_CODE(le32_to_cpu(event->status)))) {
+               if (handle_stopped_cmd_ring(xhci, cmd_comp_code)) {
                        inc_deq(xhci, xhci->cmd_ring);
                        return;
                }
@@ -1558,44 +1550,46 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
                        return;
        }
 
-       switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])
-               & TRB_TYPE_BITMASK) {
-       case TRB_TYPE(TRB_ENABLE_SLOT):
-               xhci_handle_cmd_enable_slot(xhci, slot_id,
-                               GET_COMP_CODE(le32_to_cpu(event->status)));
+       cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3]));
+       switch (cmd_type) {
+       case TRB_ENABLE_SLOT:
+               xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_DISABLE_SLOT):
+       case TRB_DISABLE_SLOT:
                xhci_handle_cmd_disable_slot(xhci, slot_id);
                break;
-       case TRB_TYPE(TRB_CONFIG_EP):
-               xhci_handle_cmd_config_ep(xhci, slot_id, event,
-                               GET_COMP_CODE(le32_to_cpu(event->status)));
+       case TRB_CONFIG_EP:
+               xhci_handle_cmd_config_ep(xhci, slot_id, event, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_EVAL_CONTEXT):
-               xhci_handle_cmd_eval_ctx(xhci, slot_id, event,
-                               GET_COMP_CODE(le32_to_cpu(event->status)));
+       case TRB_EVAL_CONTEXT:
+               xhci_handle_cmd_eval_ctx(xhci, slot_id, event, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_ADDR_DEV):
-               xhci_handle_cmd_addr_dev(xhci, slot_id,
-                               GET_COMP_CODE(le32_to_cpu(event->status)));
+       case TRB_ADDR_DEV:
+               xhci_handle_cmd_addr_dev(xhci, slot_id, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_STOP_RING):
-               xhci_handle_cmd_stop_ep(xhci, xhci->cmd_ring->dequeue, event);
+       case TRB_STOP_RING:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);
                break;
-       case TRB_TYPE(TRB_SET_DEQ):
-               xhci_handle_cmd_set_deq(xhci, event, xhci->cmd_ring->dequeue);
+       case TRB_SET_DEQ:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_set_deq(xhci, slot_id, cmd_trb, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_CMD_NOOP):
+       case TRB_CMD_NOOP:
                break;
-       case TRB_TYPE(TRB_RESET_EP):
-               xhci_handle_cmd_reset_ep(xhci, event, xhci->cmd_ring->dequeue);
+       case TRB_RESET_EP:
+               WARN_ON(slot_id != TRB_TO_SLOT_ID(
+                               le32_to_cpu(cmd_trb->generic.field[3])));
+               xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code);
                break;
-       case TRB_TYPE(TRB_RESET_DEV):
+       case TRB_RESET_DEV:
                WARN_ON(slot_id != TRB_TO_SLOT_ID(
-                               le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])));
+                               le32_to_cpu(cmd_trb->generic.field[3])));
                xhci_handle_cmd_reset_dev(xhci, slot_id, event);
                break;
-       case TRB_TYPE(TRB_NEC_GET_FW):
+       case TRB_NEC_GET_FW:
                xhci_handle_cmd_nec_get_fw(xhci, event);
                break;
        default: