DM USB: xHCI: Drop commands if the slot is disabled

From xHCI spec 4.5.3.2, the only command that software is
allowed to issue for the slot in disabled state is the Enable
Slot Command. Drop other commands in command handle function.

Tracked-On: #4711
Signed-off-by: Liu Long <longliu@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Liu Long 2020-04-24 19:12:20 +08:00 committed by wenlingz
parent 16e33b30d1
commit 77b7721fd0

View File

@ -2572,44 +2572,73 @@ pci_xhci_complete_commands(struct pci_xhci_vdev *xdev)
case XHCI_TRB_TYPE_DISABLE_SLOT: /* 0x0A */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_disable_slot(xdev, slot);
/*
* From spec 4.5.3.2 The only command that software is
* allowed to issue for the slot in disabled state
* is Enable Slot Command.
* */
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_disable_slot(xdev, slot);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_ADDRESS_DEVICE: /* 0x0B */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_address_device(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_address_device(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_CONFIGURE_EP: /* 0x0C */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_config_ep(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_config_ep(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_EVALUATE_CTX: /* 0x0D */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_eval_ctx(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_eval_ctx(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_RESET_EP: /* 0x0E */
UPRINTF(LDBG, "Reset Endpoint on slot %d\r\n", slot);
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_reset_ep(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_reset_ep(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_STOP_EP: /* 0x0F */
UPRINTF(LDBG, "Stop Endpoint on slot %d\r\n", slot);
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_reset_ep(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_reset_ep(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_SET_TR_DEQUEUE: /* 0x10 */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_set_tr(xdev, slot, trb);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_set_tr(xdev, slot, trb);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_RESET_DEVICE: /* 0x11 */
slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3);
cmderr = pci_xhci_cmd_reset_device(xdev, slot);
if (xdev->slot_allocated[slot])
cmderr = pci_xhci_cmd_reset_device(xdev, slot);
else
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
break;
case XHCI_TRB_TYPE_FORCE_EVENT: /* 0x12 */