From 77b7721fd0c6d8b92af1d06a9e3f9886cefb5745 Mon Sep 17 00:00:00 2001 From: Liu Long Date: Fri, 24 Apr 2020 19:12:20 +0800 Subject: [PATCH] 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 Acked-by: Wang, Yu1 --- devicemodel/hw/pci/xhci.c | 45 ++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index 6b72da09c..b4e453f25 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -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 */