MdeModulePkg/Xhci: Remove TDs from transfer ring when timeout happens
The error handling for timeout case is enhanced to remove TDs from transfer ring. The original code only removed s/w URB, but the h/w transfer descriptor TDs didn't get removed. It would cause data lost for data stream peripheral, such as usb-to-serial device, from the s/w perspective. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Baraneedharan Anbazhagan <anbazhagan@hp.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18313 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -648,17 +648,28 @@ XhcPeiControlTransfer (
|
||||
*TransferResult = Urb->Result;
|
||||
*DataLength = Urb->Completed;
|
||||
|
||||
if (*TransferResult == EFI_USB_NOERROR) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (*TransferResult == EFI_USB_ERR_STALL) {
|
||||
RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR (RecoveryStatus)) {
|
||||
DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));
|
||||
if (Status == EFI_TIMEOUT) {
|
||||
//
|
||||
// The transfer timed out. Abort the transfer by dequeueing of the TD.
|
||||
//
|
||||
RecoveryStatus = XhcPeiDequeueTrbFromEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR(RecoveryStatus)) {
|
||||
DEBUG((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiDequeueTrbFromEndpoint failed\n"));
|
||||
}
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto FREE_URB;
|
||||
} else {
|
||||
goto FREE_URB;
|
||||
if (*TransferResult == EFI_USB_NOERROR) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (*TransferResult == EFI_USB_ERR_STALL) {
|
||||
RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR (RecoveryStatus)) {
|
||||
DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));
|
||||
}
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto FREE_URB;
|
||||
} else {
|
||||
goto FREE_URB;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -960,14 +971,24 @@ XhcPeiBulkTransfer (
|
||||
*TransferResult = Urb->Result;
|
||||
*DataLength = Urb->Completed;
|
||||
|
||||
if (*TransferResult == EFI_USB_NOERROR) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (*TransferResult == EFI_USB_ERR_STALL) {
|
||||
RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR (RecoveryStatus)) {
|
||||
DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));
|
||||
if (Status == EFI_TIMEOUT) {
|
||||
//
|
||||
// The transfer timed out. Abort the transfer by dequeueing of the TD.
|
||||
//
|
||||
RecoveryStatus = XhcPeiDequeueTrbFromEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR(RecoveryStatus)) {
|
||||
DEBUG((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiDequeueTrbFromEndpoint failed\n"));
|
||||
}
|
||||
} else {
|
||||
if (*TransferResult == EFI_USB_NOERROR) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (*TransferResult == EFI_USB_ERR_STALL) {
|
||||
RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb);
|
||||
if (EFI_ERROR (RecoveryStatus)) {
|
||||
DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiRecoverHaltedEndpoint failed\n"));
|
||||
}
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
XhcPeiFreeUrb (Xhc, Urb);
|
||||
|
Reference in New Issue
Block a user