summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c')
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 613b1485f1..7542782049 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -2108,6 +2108,26 @@ RingIntTransferDoorBell (
}
/**
+ Set Command abort
+
+ @param Xhc The XHCI Instance.
+ @param SlotId The slot id to be disabled.
+
+**/
+VOID
+XhcCmdRingCmdAbort (
+ IN USB_XHCI_INSTANCE *Xhc,
+ IN UINT8 SlotId
+ )
+{
+ //
+ // Set XHC_CRCR_CA bit in XHC_CRCR_OFFSET to abort command.
+ //
+ DEBUG ((DEBUG_INFO, "Command Ring Control set Command Abort, SlotId: %d\n", SlotId));
+ XhcSetOpRegBit (Xhc, XHC_CRCR_OFFSET, XHC_CRCR_CA);
+}
+
+/**
Assign and initialize the device slot for a new device.
@param Xhc The XHCI Instance.
@@ -2317,6 +2337,14 @@ XhcInitializeDeviceSlot (
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
} else {
DEBUG ((DEBUG_ERROR, " Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
+ //
+ // Software may abort the execution of Address Device Command when command failed
+ // due to timeout by following XHCI spec. 4.6.1.2.
+ //
+ if (Status == EFI_TIMEOUT) {
+ XhcCmdRingCmdAbort (Xhc, SlotId);
+ }
+
XhcDisableSlotCmd (Xhc, SlotId);
}
@@ -2533,6 +2561,14 @@ XhcInitializeDeviceSlot64 (
Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
} else {
DEBUG ((DEBUG_ERROR, " Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
+ //
+ // Software may abort the execution of Address Device Command when command failed
+ // due to timeout by following XHCI spec. 4.6.1.2.
+ //
+ if (Status == EFI_TIMEOUT) {
+ XhcCmdRingCmdAbort (Xhc, SlotId);
+ }
+
XhcDisableSlotCmd64 (Xhc, SlotId);
}