upper_32_bits(val));
 }
 
-void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
+dma_addr_t xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_slot_ctx *slot, dma_addr_t dma)
 {
-       int i, j;
-       int last_ep_ctx = 31;
        /* Fields are 32 bits wide, DMA addresses are in bytes */
        int field_size = 32 / 8;
-
-       xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
-                       &ctx->drop_flags, (unsigned long long)dma,
-                       ctx->drop_flags);
-       dma += field_size;
-       xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
-                       &ctx->add_flags, (unsigned long long)dma,
-                       ctx->add_flags);
-       dma += field_size;
-       for (i = 0; i < 6; ++i) {
-               xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
-                               &ctx->rsvd[i], (unsigned long long)dma,
-                               ctx->rsvd[i], i);
-               dma += field_size;
-       }
+       int i;
 
        xhci_dbg(xhci, "Slot Context:\n");
        xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
-                       &ctx->slot.dev_info,
-                       (unsigned long long)dma, ctx->slot.dev_info);
+                       &slot->dev_info,
+                       (unsigned long long)dma, slot->dev_info);
        dma += field_size;
        xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
-                       &ctx->slot.dev_info2,
-                       (unsigned long long)dma, ctx->slot.dev_info2);
+                       &slot->dev_info2,
+                       (unsigned long long)dma, slot->dev_info2);
        dma += field_size;
        xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
-                       &ctx->slot.tt_info,
-                       (unsigned long long)dma, ctx->slot.tt_info);
+                       &slot->tt_info,
+                       (unsigned long long)dma, slot->tt_info);
        dma += field_size;
        xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
-                       &ctx->slot.dev_state,
-                       (unsigned long long)dma, ctx->slot.dev_state);
+                       &slot->dev_state,
+                       (unsigned long long)dma, slot->dev_state);
        dma += field_size;
        for (i = 0; i < 4; ++i) {
                xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
-                               &ctx->slot.reserved[i], (unsigned long long)dma,
-                               ctx->slot.reserved[i], i);
+                               &slot->reserved[i], (unsigned long long)dma,
+                               slot->reserved[i], i);
                dma += field_size;
        }
 
+       return dma;
+}
+
+dma_addr_t xhci_dbg_ep_ctx(struct xhci_hcd *xhci, struct xhci_ep_ctx *ep, dma_addr_t dma, unsigned int last_ep)
+{
+       int i, j;
+       int last_ep_ctx = 31;
+       /* Fields are 32 bits wide, DMA addresses are in bytes */
+       int field_size = 32 / 8;
+
        if (last_ep < 31)
                last_ep_ctx = last_ep + 1;
        for (i = 0; i < last_ep_ctx; ++i) {
                xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
                xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
-                               &ctx->ep[i].ep_info,
-                               (unsigned long long)dma, ctx->ep[i].ep_info);
+                               &ep[i].ep_info,
+                               (unsigned long long)dma, ep[i].ep_info);
                dma += field_size;
                xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
-                               &ctx->ep[i].ep_info2,
-                               (unsigned long long)dma, ctx->ep[i].ep_info2);
+                               &ep[i].ep_info2,
+                               (unsigned long long)dma, ep[i].ep_info2);
                dma += field_size;
                xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
-                               &ctx->ep[i].deq,
-                               (unsigned long long)dma, ctx->ep[i].deq);
+                               &ep[i].deq,
+                               (unsigned long long)dma, ep[i].deq);
                dma += 2*field_size;
                xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
-                               &ctx->ep[i].tx_info,
-                               (unsigned long long)dma, ctx->ep[i].tx_info);
+                               &ep[i].tx_info,
+                               (unsigned long long)dma, ep[i].tx_info);
                dma += field_size;
                for (j = 0; j < 3; ++j) {
                        xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
-                                       &ctx->ep[i].reserved[j],
+                                       &ep[i].reserved[j],
                                        (unsigned long long)dma,
-                                       ctx->ep[i].reserved[j], j);
+                                       ep[i].reserved[j], j);
                        dma += field_size;
                }
        }
+       return dma;
+}
+
+void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
+{
+       int i;
+       /* Fields are 32 bits wide, DMA addresses are in bytes */
+       int field_size = 32 / 8;
+
+       xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
+                       &ctx->drop_flags, (unsigned long long)dma,
+                       ctx->drop_flags);
+       dma += field_size;
+       xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
+                       &ctx->add_flags, (unsigned long long)dma,
+                       ctx->add_flags);
+       dma += field_size;
+       for (i = 0; i < 6; ++i) {
+               xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
+                               &ctx->rsvd[i], (unsigned long long)dma,
+                               ctx->rsvd[i], i);
+               dma += field_size;
+       }
+       dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma);
+       dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep);
+}
+
+void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep)
+{
+       dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma);
+       dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep);
 }
 
        }
 
        xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
-       xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma,
+       xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma,
                        LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info));
 
        xhci_zero_in_ctx(virt_dev);
        xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
        xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2);
        xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
-       xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2);
+       xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2);
        /*
         * USB core uses address 1 for the roothubs, so we add one to the
         * address given back to us by the HC.
        /* Zero the input context control for later use */
        virt_dev->in_ctx->add_flags = 0;
        virt_dev->in_ctx->drop_flags = 0;
-       /* Mirror flags in the output context for future ep enable/disable */
-       virt_dev->out_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
-       virt_dev->out_ctx->drop_flags = 0;
 
        xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
        /* XXX Meh, not sure if anyone else but choose_address uses this. */
 
 
 /**
  * struct xhci_device_control
- * Input/Output context; see section 6.2.5.
+ * Input context; see section 6.2.5.
  *
  * @drop_context:      set the bit of the endpoint context you want to disable
  * @add_context:       set the bit of the endpoint context you want to enable
  */
 struct xhci_device_control {
+       /* Input control context */
        u32     drop_flags;
        u32     add_flags;
        u32     rsvd[6];
+       /* Copy of device context */
+       struct xhci_slot_ctx    slot;
+       struct xhci_ep_ctx      ep[31];
+};
+
+/**
+ * struct xhci_device_ctx
+ * Device context; see section 6.2.1.
+ *
+ * @slot:              slot context for the device.
+ * @ep:                        array of endpoint contexts for the device.
+ */
+struct xhci_device_ctx {
        struct xhci_slot_ctx    slot;
        struct xhci_ep_ctx      ep[31];
 };
         * track of input and output contexts separately because
         * these commands might fail and we don't trust the hardware.
         */
-       struct xhci_device_control      *out_ctx;
+       struct xhci_device_ctx          *out_ctx;
        dma_addr_t                      out_ctx_dma;
        /* Used for addressing devices and configuration changes */
        struct xhci_device_control      *in_ctx;
 void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
 void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
 void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep);
+void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep);
 
 /* xHCI memory managment */
 void xhci_mem_cleanup(struct xhci_hcd *xhci);