\r
Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);\r
\r
- *TransferResult = Urb->Result;\r
- *DataLength = Urb->Completed;\r
-\r
if (Status == EFI_TIMEOUT) {\r
//\r
// The transfer timed out. Abort the transfer by dequeueing of the TD.\r
//\r
- RecoveryStatus = XhcDequeueTrbFromEndpoint (Xhc, Urb);\r
- if (EFI_ERROR (RecoveryStatus)) {\r
- DEBUG((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcDequeueTrbFromEndpoint failed\n", Type));\r
- }\r
- } else {\r
- if (*TransferResult == EFI_USB_NOERROR) {\r
+ RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);\r
+ if (RecoveryStatus == EFI_ALREADY_STARTED) {\r
+ //\r
+ // The URB is finished just before stopping endpoint.\r
+ // Change returning status from EFI_TIMEOUT to EFI_SUCCESS.\r
+ //\r
+ ASSERT (Urb->Result == EFI_USB_NOERROR);\r
Status = EFI_SUCCESS;\r
- } else if (*TransferResult == EFI_USB_ERR_STALL) {\r
- RecoveryStatus = XhcRecoverHaltedEndpoint (Xhc, Urb);\r
- if (EFI_ERROR (RecoveryStatus)) {\r
- DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcRecoverHaltedEndpoint failed\n", Type));\r
- }\r
- Status = EFI_DEVICE_ERROR;\r
+ DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: pending URB is finished, Length = %d.\n", Type, Urb->Completed));\r
+ } else if (EFI_ERROR(RecoveryStatus)) {\r
+ DEBUG((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcDequeueTrbFromEndpoint failed!\n", Type));\r
+ }\r
+ }\r
+\r
+ *TransferResult = Urb->Result;\r
+ *DataLength = Urb->Completed;\r
+\r
+ if (*TransferResult == EFI_USB_ERR_STALL) {\r
+ ASSERT (Status == EFI_DEVICE_ERROR);\r
+ RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);\r
+ if (EFI_ERROR (RecoveryStatus)) {\r
+ DEBUG ((DEBUG_ERROR, "XhcTransfer[Type=%d]: XhcRecoverHaltedEndpoint failed!\n", Type));\r
}\r
}\r
\r