This commit is contained in:
Sean Rhodes 2026-08-13 11:20:19 -07:00 committed by GitHub
commit edf9fe2314
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 82 additions and 3 deletions

View file

@ -819,6 +819,7 @@ XhcTransfer (
DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: pending URB is finished, Length = %d.\n", Type, Urb->Completed));
} else if (EFI_ERROR (RecoveryStatus)) {
DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcDequeueTrbFromEndpoint failed!\n", Type));
Status = RecoveryStatus;
}
}

View file

@ -1311,6 +1311,58 @@ EXIT:
return Urb->Finished;
}
/**
Check whether an endpoint is in the Running state.
@param Xhc The XHCI instance.
@param SlotId The slot id.
@param Dci The device context index.
@retval TRUE The endpoint is in the Running state.
@retval FALSE The endpoint is not in the Running state.
**/
STATIC
BOOLEAN
EFIAPI
XhcEndpointRunning (
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 Dci
)
{
DEVICE_CONTEXT *OutputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
return OutputContext && OutputContext->EP[Dci - 1].EPState == 1;
}
/**
Check whether an endpoint is in the Halted state.
@param Xhc The XHCI instance.
@param SlotId The slot id.
@param Dci The device context index.
@retval TRUE The endpoint is in the Halted state.
@retval FALSE The endpoint is not in the Halted state.
**/
STATIC
BOOLEAN
EFIAPI
XhcEndpointHalted (
IN USB_XHCI_INSTANCE *Xhc,
IN UINT8 SlotId,
IN UINT8 Dci
)
{
DEVICE_CONTEXT *OutputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
return OutputContext && OutputContext->EP[Dci - 1].EPState == 2;
}
/**
Execute the transfer by polling the URB. This is a synchronous operation.
@ -1359,6 +1411,10 @@ XhcExecTransfer (
ASSERT (Dci < 32);
}
if (!CmdTransfer && XhcEndpointHalted (Xhc, SlotId, Dci)) {
goto DONE;
}
if (Timeout == 0) {
IndefiniteTimeout = TRUE;
}
@ -1389,9 +1445,15 @@ XhcExecTransfer (
ElapsedTicks += TicksDelta;
} while (IndefiniteTimeout || ElapsedTicks < TimeoutTicks);
DONE:
if (!Finished) {
Urb->Result = EFI_USB_ERR_TIMEOUT;
Status = EFI_TIMEOUT;
if (XhcEndpointHalted (Xhc, SlotId, Dci)) {
Urb->Result = EFI_USB_ERR_STALL;
Status = EFI_DEVICE_ERROR;
} else {
Urb->Result = EFI_USB_ERR_TIMEOUT;
Status = EFI_TIMEOUT;
}
} else if (Urb->Result != EFI_USB_NOERROR) {
Status = EFI_DEVICE_ERROR;
}
@ -3518,6 +3580,22 @@ XhcStopEndpoint (
EvtTrb = NULL;
if (XhcEndpointHalted (Xhc, SlotId, Dci)) {
if (PendingUrb != NULL) {
PendingUrb->Result = EFI_USB_ERR_STALL;
}
return EFI_DEVICE_ERROR;
}
if (!XhcEndpointRunning (Xhc, SlotId, Dci)) {
if (PendingUrb != NULL) {
PendingUrb->Result = EFI_USB_ERR_SYSTEM;
}
return EFI_DEVICE_ERROR;
}
//
// When XhcCheckUrbResult waits for the Stop_Endpoint completion, it also checks
// the PendingUrb completion status, because it's possible that the PendingUrb is

View file

@ -281,7 +281,7 @@ UsbBootExecCmdWithRetry (
DataLen,
Timeout
);
if ((Status == EFI_SUCCESS) || (Status == EFI_NO_MEDIA)) {
if ((Status == EFI_SUCCESS) || (Status == EFI_NO_MEDIA) || (Status == EFI_DEVICE_ERROR)) {
break;
}