Timeout,\r
&CmdResult\r
);\r
+\r
+ if (Status == EFI_TIMEOUT) {\r
+ DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: Timeout to Exec 0x%x Cmd\n", *(UINT8 *)Cmd));\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
//\r
// If ExecCommand() returns no error and CmdResult is success,\r
// then the commnad transfer is successful.\r
return EFI_SUCCESS;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UsbBootExecCmd: Fail to Exec 0x%x Cmd /w %r\n",\r
- *(UINT8 *)Cmd ,Status));\r
-\r
//\r
// If command execution failed, then retrieve error info via sense request.\r
//\r
{\r
EFI_STATUS Status;\r
UINTN Retry;\r
- UINT8 Terminate;\r
+ EFI_EVENT TimeoutEvt;\r
+\r
+ Retry = 0;\r
+ Status = EFI_SUCCESS;\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_CALLBACK,\r
+ NULL,\r
+ NULL,\r
+ &TimeoutEvt\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- Status = EFI_SUCCESS;\r
+ Status = gBS->SetTimer (TimeoutEvt, TimerRelative, EFI_TIMER_PERIOD_SECONDS(60));\r
+ if (EFI_ERROR (Status)) {\r
+ goto EXIT;\r
+ }\r
\r
- for (Retry = 0, Terminate = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) {\r
+ //\r
+ // Execute the cmd and retry if it fails.\r
+ //\r
+ while (EFI_ERROR (gBS->CheckEvent (TimeoutEvt))) {\r
Status = UsbBootExecCmd (\r
UsbMass,\r
Cmd,\r
DataLen,\r
Timeout\r
);\r
- if (Status == EFI_SUCCESS || Status == EFI_MEDIA_CHANGED) {\r
+ if (Status == EFI_SUCCESS || Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA) {\r
break;\r
}\r
//\r
- // If the device isn't ready, just wait for it without limit on retrial times.\r
+ // If the sense data shows the drive is not ready, we need execute the cmd again.\r
+ // We limit the upper boundary to 60 seconds.\r
+ //\r
+ if (Status == EFI_NOT_READY) {\r
+ continue;\r
+ }\r
+ //\r
+ // If the status is other error, then just retry 5 times.\r
//\r
- if (Status == EFI_NOT_READY && Terminate < 3) {\r
- Retry = 0;\r
- Terminate++;\r
+ if (Retry++ >= USB_BOOT_COMMAND_RETRY) {\r
+ break;\r
}\r
}\r
\r
+EXIT:\r
+ if (TimeoutEvt != NULL) {\r
+ gBS->CloseEvent (TimeoutEvt);\r
+ }\r
+\r
return Status;\r
}\r
\r
Media->BlockSize = 0x0800;\r
}\r
\r
- if ((UsbMass->Pdt != USB_PDT_CDROM) && (CmdSet == USB_MASS_STORE_SCSI)) {\r
- //\r
- // ModeSense is required for the device with PDT of 0x00/0x07/0x0E,\r
- // which is from [MassStorageBootabilitySpec-Page7].\r
- // ModeSense(10) is useless here, while ModeSense(6) defined in SCSI\r
- // could get the information of WriteProtected.\r
- // Since not all device support this command, so skip if fail.\r
- //\r
- UsbScsiModeSense (UsbMass);\r
- }\r
+ Status = UsbBootDetectMedia (UsbMass);\r
\r
- return UsbBootReadCapacity (UsbMass);\r
+ return Status;\r
}\r
\r
\r
CmdSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;\r
\r
Status = UsbBootIsUnitReady (UsbMass);\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {\r
goto ON_ERROR;\r
}\r
\r
{\r
EFI_BLOCK_IO_MEDIA *Media;\r
EFI_STATUS Status;\r
- UINTN Index;\r
\r
Media = &UsbMass->BlockIoMedia;\r
\r
Media->IoAlign = 0;\r
Media->MediaId = 1;\r
\r
- //\r
- // Some device may spend several seconds before it is ready.\r
- // Try several times before giving up. Wait 5s at most.\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- for (Index = 0; Index < USB_BOOT_INIT_MEDIA_RETRY; Index++) {\r
-\r
- Status = UsbBootGetParams (UsbMass);\r
- if ((Status != EFI_MEDIA_CHANGED) && (Status != EFI_NOT_READY) && (Status != EFI_TIMEOUT)) {\r
- break;\r
- }\r
-\r
- Status = UsbBootIsUnitReady (UsbMass);\r
- if (EFI_ERROR (Status)) {\r
- gBS->Stall (USB_BOOT_RETRY_UNIT_READY_STALL * (Index + 1));\r
- }\r
- }\r
-\r
+ Status = UsbBootGetParams (UsbMass);\r
return Status;\r
}\r
\r