mirror of https://github.com/acidanthera/audk.git
Media detection logic is enhanced to be more robust.
Signed-off-by: erictian Reviewed-by: hhuan13 Reviewed-by: mdkinney git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12289 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
ec2bb58802
commit
ae5dc79532
|
@ -697,27 +697,50 @@ ScsiDiskDetectMedia (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_STATUS ReadCapacityStatus;
|
|
||||||
EFI_SCSI_SENSE_DATA *SenseData;
|
EFI_SCSI_SENSE_DATA *SenseData;
|
||||||
UINTN NumberOfSenseKeys;
|
UINTN NumberOfSenseKeys;
|
||||||
BOOLEAN NeedRetry;
|
BOOLEAN NeedRetry;
|
||||||
BOOLEAN NeedReadCapacity;
|
BOOLEAN NeedReadCapacity;
|
||||||
UINT8 Index;
|
UINT8 Retry;
|
||||||
UINT8 MaxRetry;
|
UINT8 MaxRetry;
|
||||||
EFI_BLOCK_IO_MEDIA OldMedia;
|
EFI_BLOCK_IO_MEDIA OldMedia;
|
||||||
UINTN Action;
|
UINTN Action;
|
||||||
|
EFI_EVENT TimeoutEvt;
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
ReadCapacityStatus = EFI_SUCCESS;
|
|
||||||
SenseData = NULL;
|
SenseData = NULL;
|
||||||
NumberOfSenseKeys = 0;
|
NumberOfSenseKeys = 0;
|
||||||
NeedReadCapacity = FALSE;
|
Retry = 0;
|
||||||
CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));
|
|
||||||
*MediaChange = FALSE;
|
|
||||||
MaxRetry = 3;
|
MaxRetry = 3;
|
||||||
Action = ACTION_NO_ACTION;
|
Action = ACTION_NO_ACTION;
|
||||||
|
NeedReadCapacity = FALSE;
|
||||||
|
*MediaChange = FALSE;
|
||||||
|
TimeoutEvt = NULL;
|
||||||
|
|
||||||
for (Index = 0; Index < MaxRetry; Index++) {
|
CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_TIMER,
|
||||||
|
TPL_CALLBACK,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&TimeoutEvt
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->SetTimer (TimeoutEvt, TimerRelative, EFI_TIMER_PERIOD_SECONDS(120));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sending Test_Unit cmd to poll device status.
|
||||||
|
// If the sense data shows the drive is not ready or reset before, we need poll the device status again.
|
||||||
|
// We limit the upper boundary to 120 seconds.
|
||||||
|
//
|
||||||
|
while (EFI_ERROR (gBS->CheckEvent (TimeoutEvt))) {
|
||||||
Status = ScsiDiskTestUnitReady (
|
Status = ScsiDiskTestUnitReady (
|
||||||
ScsiDiskDevice,
|
ScsiDiskDevice,
|
||||||
&NeedRetry,
|
&NeedRetry,
|
||||||
|
@ -732,21 +755,22 @@ ScsiDiskDetectMedia (
|
||||||
&Action
|
&Action
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
goto EXIT;
|
||||||
} else if (Action == ACTION_RETRY_COMMAND_LATER) {
|
} else if (Action == ACTION_RETRY_COMMAND_LATER) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Retry++;
|
||||||
|
if (!NeedRetry || (Retry >= MaxRetry)) {
|
||||||
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NeedRetry) {
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Index == MaxRetry) && EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -765,18 +789,14 @@ ScsiDiskDetectMedia (
|
||||||
//
|
//
|
||||||
// retrieve media information
|
// retrieve media information
|
||||||
//
|
//
|
||||||
MaxRetry = 3;
|
for (Retry = 0; Retry < MaxRetry; Retry++) {
|
||||||
for (Index = 0; Index < MaxRetry; Index++) {
|
Status = ScsiDiskReadCapacity (
|
||||||
|
|
||||||
ReadCapacityStatus = ScsiDiskReadCapacity (
|
|
||||||
ScsiDiskDevice,
|
ScsiDiskDevice,
|
||||||
&NeedRetry,
|
&NeedRetry,
|
||||||
&SenseData,
|
&SenseData,
|
||||||
&NumberOfSenseKeys
|
&NumberOfSenseKeys
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (ReadCapacityStatus) && !NeedRetry) {
|
if (!EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// analyze sense key to action
|
// analyze sense key to action
|
||||||
//
|
//
|
||||||
|
@ -786,42 +806,28 @@ ScsiDiskDetectMedia (
|
||||||
NumberOfSenseKeys,
|
NumberOfSenseKeys,
|
||||||
&Action
|
&Action
|
||||||
);
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// if Status is error, it may indicate crisis error,
|
// if Status is error, it may indicate crisis error,
|
||||||
// so return without retry.
|
// so return without retry.
|
||||||
//
|
//
|
||||||
|
goto EXIT;
|
||||||
|
} else if (Action == ACTION_RETRY_COMMAND_LATER) {
|
||||||
|
Retry = 0;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Retry++;
|
||||||
|
if (!NeedRetry || (Retry >= MaxRetry)) {
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
goto EXIT;
|
||||||
}
|
|
||||||
|
|
||||||
switch (Action) {
|
|
||||||
case ACTION_NO_ACTION:
|
|
||||||
//
|
|
||||||
// no retry
|
|
||||||
//
|
|
||||||
Index = MaxRetry;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACTION_RETRY_COMMAND_LATER:
|
|
||||||
//
|
|
||||||
// retry the ReadCapacity later and continuously, until the condition
|
|
||||||
// no longer emerges.
|
|
||||||
// stall time is 100000us, or say 0.1 second.
|
|
||||||
//
|
|
||||||
gBS->Stall (100000);
|
|
||||||
Index = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//
|
|
||||||
// other cases, just retry the command
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Index == MaxRetry) && EFI_ERROR (ReadCapacityStatus)) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,7 +869,11 @@ ScsiDiskDetectMedia (
|
||||||
*MediaChange = TRUE;
|
*MediaChange = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
EXIT:
|
||||||
|
if (TimeoutEvt != NULL) {
|
||||||
|
gBS->CloseEvent (TimeoutEvt);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1188,7 +1198,9 @@ DetectMediaParsingSenseKeys (
|
||||||
*Action = ACTION_READ_CAPACITY;
|
*Action = ACTION_READ_CAPACITY;
|
||||||
|
|
||||||
if (NumberOfSenseKeys == 0) {
|
if (NumberOfSenseKeys == 0) {
|
||||||
|
if (ScsiDiskDevice->BlkIo.Media->MediaPresent == TRUE) {
|
||||||
*Action = ACTION_NO_ACTION;
|
*Action = ACTION_NO_ACTION;
|
||||||
|
}
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,7 +1208,9 @@ DetectMediaParsingSenseKeys (
|
||||||
//
|
//
|
||||||
// No Sense Key returned from last submitted command
|
// No Sense Key returned from last submitted command
|
||||||
//
|
//
|
||||||
|
if (ScsiDiskDevice->BlkIo.Media->MediaPresent == TRUE) {
|
||||||
*Action = ACTION_NO_ACTION;
|
*Action = ACTION_NO_ACTION;
|
||||||
|
}
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,10 +1234,12 @@ DetectMediaParsingSenseKeys (
|
||||||
if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {
|
if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {
|
||||||
ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
|
ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
|
||||||
ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
|
ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
|
||||||
|
*Action = ACTION_NO_ACTION;
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {
|
if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {
|
||||||
|
*Action = ACTION_NO_ACTION;
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,7 +1248,7 @@ DetectMediaParsingSenseKeys (
|
||||||
*Action = ACTION_RETRY_COMMAND_LATER;
|
*Action = ACTION_RETRY_COMMAND_LATER;
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
*Action = ACTION_NO_ACTION;
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue