diff options
author | erictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-06-14 02:11:34 +0000 |
---|---|---|
committer | erictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-06-14 02:11:34 +0000 |
commit | cbd2a4b3628d3242620bb5353e4b466bc435ca87 (patch) | |
tree | d8fc4d6f4d7d16b5ab7a179e8eef7a41cca71f44 /MdeModulePkg/Bus/Scsi | |
parent | e118a40b9d1c1f06c96eda16fbb96a0d000f8a11 (diff) | |
download | edk2-cbd2a4b3628d3242620bb5353e4b466bc435ca87.zip edk2-cbd2a4b3628d3242620bb5353e4b466bc435ca87.tar.gz edk2-cbd2a4b3628d3242620bb5353e4b466bc435ca87.tar.bz2 |
ScsiBus/ScsiDisk enhancement for no_media state.
Ahci enumeration logic tuning for boot performance.
Signed-off-by:erictian
Reviewed-by:qianouyang, hhuan13
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11820 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Bus/Scsi')
-rw-r--r-- | MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c | 191 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 40 |
2 files changed, 144 insertions, 87 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c b/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c index e6d9636..bfb36df 100644 --- a/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c +++ b/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c @@ -1026,10 +1026,63 @@ ScsiScanCreateDevice ( EFI_STATUS Status;
SCSI_IO_DEV *ScsiIoDevice;
EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
+ EFI_HANDLE DeviceHandle;
+
+ DevicePath = NULL;
+ RemainingDevicePath = NULL;
+ ScsiDevicePath = NULL;
+ ScsiIoDevice = NULL;
+
+ //
+ // Build Device Path
+ //
+ if (ScsiBusDev->ExtScsiSupport){
+ Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (
+ ScsiBusDev->ExtScsiInterface,
+ &TargetId->ScsiId.ExtScsi[0],
+ Lun,
+ &ScsiDevicePath
+ );
+ } else {
+ Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (
+ ScsiBusDev->ScsiInterface,
+ TargetId->ScsiId.Scsi,
+ Lun,
+ &ScsiDevicePath
+ );
+ }
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ DevicePath = AppendDevicePathNode (
+ ScsiBusDev->DevicePath,
+ ScsiDevicePath
+ );
+
+ if (DevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ DeviceHandle = NULL;
+ RemainingDevicePath = DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
+ if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
+ //
+ // The device has been started, directly return to fast boot.
+ //
+ Status = EFI_ALREADY_STARTED;
+ goto ErrorExit;
+ }
ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));
if (ScsiIoDevice == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
}
ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;
@@ -1053,52 +1106,12 @@ ScsiScanCreateDevice ( ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;
ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;
-
if (!DiscoverScsiDevice (ScsiIoDevice)) {
- FreePool (ScsiIoDevice);
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
}
- //
- // Set Device Path
- //
- ScsiDevicePath = NULL;
- if (ScsiIoDevice->ExtScsiSupport){
- Status = ScsiIoDevice->ExtScsiPassThru->BuildDevicePath (
- ScsiIoDevice->ExtScsiPassThru,
- &ScsiIoDevice->Pun.ScsiId.ExtScsi[0],
- ScsiIoDevice->Lun,
- &ScsiDevicePath
- );
- } else {
- Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (
- ScsiIoDevice->ScsiPassThru,
- ScsiIoDevice->Pun.ScsiId.Scsi,
- ScsiIoDevice->Lun,
- &ScsiDevicePath
- );
- }
-
- if (EFI_ERROR(Status)) {
- FreePool (ScsiIoDevice);
- return Status;
- }
-
- ScsiIoDevice->DevicePath = AppendDevicePathNode (
- ScsiBusDev->DevicePath,
- ScsiDevicePath
- );
- //
- // The memory space for ScsiDevicePath is allocated in
- // ScsiPassThru->BuildDevicePath() function; It is no longer used
- // after EfiAppendDevicePathNode,so free the memory it occupies.
- //
- FreePool (ScsiDevicePath);
-
- if (ScsiIoDevice->DevicePath == NULL) {
- FreePool (ScsiIoDevice);
- return EFI_OUT_OF_RESOURCES;
- }
+ ScsiIoDevice->DevicePath = DevicePath;
Status = gBS->InstallMultipleProtocolInterfaces (
&ScsiIoDevice->Handle,
@@ -1109,31 +1122,48 @@ ScsiScanCreateDevice ( NULL
);
if (EFI_ERROR (Status)) {
- FreePool (ScsiIoDevice->DevicePath);
- FreePool (ScsiIoDevice);
- return EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
} else {
if (ScsiBusDev->ExtScsiSupport) {
gBS->OpenProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- (VOID **) &(ScsiBusDev->ExtScsiInterface),
- This->DriverBindingHandle,
- ScsiIoDevice->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
+ Controller,
+ &gEfiExtScsiPassThruProtocolGuid,
+ (VOID **) &(ScsiBusDev->ExtScsiInterface),
+ This->DriverBindingHandle,
+ ScsiIoDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
} else {
gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- (VOID **) &(ScsiBusDev->ScsiInterface),
- This->DriverBindingHandle,
- ScsiIoDevice->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ (VOID **) &(ScsiBusDev->ScsiInterface),
+ This->DriverBindingHandle,
+ ScsiIoDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
}
}
return EFI_SUCCESS;
+
+ErrorExit:
+
+ //
+ // The memory space for ScsiDevicePath is allocated in
+ // ScsiPassThru->BuildDevicePath() function; It is no longer used
+ // after AppendDevicePathNode,so free the memory it occupies.
+ //
+ FreePool (ScsiDevicePath);
+
+ if (DevicePath != NULL) {
+ FreePool (DevicePath);
+ }
+
+ if (ScsiIoDevice != NULL) {
+ FreePool (ScsiIoDevice);
+ }
+
+ return Status;
}
@@ -1158,6 +1188,8 @@ DiscoverScsiDevice ( UINT8 TargetStatus;
EFI_SCSI_SENSE_DATA SenseData;
EFI_SCSI_INQUIRY_DATA InquiryData;
+ UINT8 MaxRetry;
+ UINT8 Index;
HostAdapterStatus = 0;
TargetStatus = 0;
@@ -1166,21 +1198,34 @@ DiscoverScsiDevice ( //
InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
SenseDataLength = (UINT8) sizeof (EFI_SCSI_SENSE_DATA);
+ ZeroMem (&InquiryData, InquiryDataLength);
+
+ MaxRetry = 2;
+ for (Index = 0; Index < MaxRetry; Index++) {
+ Status = ScsiInquiryCommand (
+ &ScsiIoDevice->ScsiIo,
+ EFI_TIMER_PERIOD_SECONDS (1),
+ (VOID *) &SenseData,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &InquiryData,
+ &InquiryDataLength,
+ FALSE
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ } else if ((Status == EFI_BAD_BUFFER_SIZE) ||
+ (Status == EFI_INVALID_PARAMETER) ||
+ (Status == EFI_UNSUPPORTED)) {
+ return FALSE;
+ }
+ }
- Status = ScsiInquiryCommand (
- &ScsiIoDevice->ScsiIo,
- EFI_TIMER_PERIOD_SECONDS (1),
- (VOID *) &SenseData,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- (VOID *) &InquiryData,
- &InquiryDataLength,
- FALSE
- );
- if (EFI_ERROR (Status) && Status != EFI_BAD_BUFFER_SIZE) {
+ if (Index == MaxRetry) {
return FALSE;
}
+
//
// Retrieved inquiry data successfully
//
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c index f0e1099..e9a7788 100644 --- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c +++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c @@ -166,6 +166,9 @@ ScsiDiskDriverBindingStart ( UINT8 Index;
UINT8 MaxRetry;
BOOLEAN NeedRetry;
+ BOOLEAN MustReadCapacity;
+
+ MustReadCapacity = TRUE;
ScsiDiskDevice = (SCSI_DISK_DEV *) AllocateZeroPool (sizeof (SCSI_DISK_DEV));
if (ScsiDiskDevice == NULL) {
@@ -199,10 +202,12 @@ ScsiDiskDriverBindingStart ( switch (ScsiDiskDevice->DeviceType) {
case EFI_SCSI_TYPE_DISK:
ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;
+ MustReadCapacity = TRUE;
break;
case EFI_SCSI_TYPE_CDROM:
ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;
+ MustReadCapacity = FALSE;
break;
}
//
@@ -249,7 +254,7 @@ ScsiDiskDriverBindingStart ( // The second parameter "TRUE" means must
// retrieve media capacity
//
- Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);
+ Status = ScsiDiskDetectMedia (ScsiDiskDevice, MustReadCapacity, &Temp);
if (!EFI_ERROR (Status)) {
//
// Determine if Block IO should be produced on this controller handle
@@ -710,6 +715,7 @@ ScsiDiskDetectMedia ( CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));
*MediaChange = FALSE;
MaxRetry = 3;
+ Action = ACTION_NO_ACTION;
for (Index = 0; Index < MaxRetry; Index++) {
Status = ScsiDiskTestUnitReady (
@@ -719,7 +725,19 @@ ScsiDiskDetectMedia ( &NumberOfSenseKeys
);
if (!EFI_ERROR (Status)) {
- break;
+ Status = DetectMediaParsingSenseKeys (
+ ScsiDiskDevice,
+ SenseData,
+ NumberOfSenseKeys,
+ &Action
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else if (Action == ACTION_RETRY_COMMAND_LATER) {
+ continue;
+ } else {
+ break;
+ }
}
if (!NeedRetry) {
@@ -731,22 +749,11 @@ ScsiDiskDetectMedia ( return EFI_DEVICE_ERROR;
}
- Status = DetectMediaParsingSenseKeys (
- ScsiDiskDevice,
- SenseData,
- NumberOfSenseKeys,
- &Action
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
//
// ACTION_NO_ACTION: need not read capacity
// other action code: need read capacity
//
- if (Action == ACTION_NO_ACTION) {
- NeedReadCapacity = FALSE;
- } else {
+ if (Action == ACTION_READ_CAPACITY) {
NeedReadCapacity = TRUE;
}
@@ -1205,6 +1212,11 @@ DetectMediaParsingSenseKeys ( return EFI_SUCCESS;
}
+ if (ScsiDiskIsResetBefore (SenseData, NumberOfSenseKeys)) {
+ *Action = ACTION_RETRY_COMMAND_LATER;
+ return EFI_SUCCESS;
+ }
+
if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {
ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
|