complete(&xhci->addr_dev);
}
+static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
+{
+ struct xhci_virt_device *virt_dev;
+
+ virt_dev = xhci->devs[slot_id];
+ if (!virt_dev)
+ return;
+ if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
+ /* Delete default control endpoint resources */
+ xhci_free_device_endpoint_resources(xhci, virt_dev, true);
+ xhci_free_virt_device(xhci, slot_id);
+}
+
+static void xhci_handle_cmd_addr_dev(struct xhci_hcd *xhci, int slot_id,
+ u32 cmd_comp_code)
+{
+ xhci->devs[slot_id]->cmd_status = cmd_comp_code;
+ complete(&xhci->addr_dev);
+}
+
static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
{
GET_COMP_CODE(le32_to_cpu(event->status)));
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
- if (xhci->devs[slot_id]) {
- if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
- /* Delete default control endpoint resources */
- xhci_free_device_endpoint_resources(xhci,
- xhci->devs[slot_id], true);
- xhci_free_virt_device(xhci, slot_id);
- }
+ xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_TYPE(TRB_CONFIG_EP):
virt_dev = xhci->devs[slot_id];
complete(&xhci->devs[slot_id]->cmd_completion);
break;
case TRB_TYPE(TRB_ADDR_DEV):
- xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status));
- complete(&xhci->addr_dev);
+ xhci_handle_cmd_addr_dev(xhci, slot_id,
+ GET_COMP_CODE(le32_to_cpu(event->status)));
break;
case TRB_TYPE(TRB_STOP_RING):
xhci_handle_cmd_stop_ep(xhci, xhci->cmd_ring->dequeue, event);
xhci_handle_cmd_reset_ep(xhci, event, xhci->cmd_ring->dequeue);
break;
case TRB_TYPE(TRB_RESET_DEV):
+ WARN_ON(slot_id != TRB_TO_SLOT_ID(
+ le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])));
xhci_dbg(xhci, "Completed reset device command.\n");
- slot_id = TRB_TO_SLOT_ID(
- le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]));
virt_dev = xhci->devs[slot_id];
if (virt_dev)
handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);