summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c')
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c2354
1 files changed, 0 insertions, 2354 deletions
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
deleted file mode 100644
index 9b3c01f824..0000000000
--- a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
+++ /dev/null
@@ -1,2354 +0,0 @@
-/*++
-
-Copyright (c) 2006 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- ScsiDisk.c
-
-Abstract:
-
---*/
-
-#include "ScsiDisk.h"
-
-EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding = {
- ScsiDiskDriverBindingSupported,
- ScsiDiskDriverBindingStart,
- ScsiDiskDriverBindingStop,
- 0xa,
- NULL,
- NULL
-};
-
-EFI_STATUS
-EFIAPI
-ScsiDiskDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-/*++
-
- Routine Description:
-
- Arguments:
-
- Returns:
-
---*/
-// TODO: This - add argument and description to function comment
-// TODO: Controller - add argument and description to function comment
-// TODO: RemainingDevicePath - add argument and description to function comment
-{
- EFI_STATUS Status;
- EFI_SCSI_IO_PROTOCOL *ScsiIo;
- UINT8 DeviceType;
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- (VOID **) &ScsiIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = ScsiIo->GetDeviceType (ScsiIo, &DeviceType);
- if (!EFI_ERROR (Status)) {
- if ((DeviceType == EFI_SCSI_TYPE_DISK) || (DeviceType == EFI_SCSI_TYPE_CDROM)) {
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_UNSUPPORTED;
- }
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-ScsiDiskDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-/*++
-
- Routine Description:
-
- Arguments:
-
- Returns:
-
---*/
-// TODO: This - add argument and description to function comment
-// TODO: Controller - add argument and description to function comment
-// TODO: RemainingDevicePath - add argument and description to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_SUCCESS - add return value to function comment
-{
- EFI_STATUS Status;
- EFI_SCSI_IO_PROTOCOL *ScsiIo;
- SCSI_DISK_DEV *ScsiDiskDevice;
- BOOLEAN Temp;
- UINT8 Index;
- UINT8 MaxRetry;
- BOOLEAN NeedRetry;
-
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- sizeof (SCSI_DISK_DEV),
- (VOID **) &ScsiDiskDevice
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ZeroMem (ScsiDiskDevice, sizeof (SCSI_DISK_DEV));
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- (VOID **) &ScsiIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (ScsiDiskDevice);
- return Status;
- }
-
- ScsiDiskDevice->Signature = SCSI_DISK_DEV_SIGNATURE;
- ScsiDiskDevice->ScsiIo = ScsiIo;
- ScsiDiskDevice->BlkIo.Media = &ScsiDiskDevice->BlkIoMedia;
- ScsiDiskDevice->BlkIo.Reset = ScsiDiskReset;
- ScsiDiskDevice->BlkIo.ReadBlocks = ScsiDiskReadBlocks;
- ScsiDiskDevice->BlkIo.WriteBlocks = ScsiDiskWriteBlocks;
- ScsiDiskDevice->BlkIo.FlushBlocks = ScsiDiskFlushBlocks;
- ScsiDiskDevice->Handle = Controller;
-
- ScsiIo->GetDeviceType (ScsiIo, &(ScsiDiskDevice->DeviceType));
- switch (ScsiDiskDevice->DeviceType) {
- case EFI_SCSI_TYPE_DISK:
- ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;
- break;
-
- case EFI_SCSI_TYPE_CDROM:
- ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;
- break;
- }
- //
- // The Sense Data Array's initial size is 6
- //
- ScsiDiskDevice->SenseDataNumber = 6;
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber,
- (VOID **) &(ScsiDiskDevice->SenseData)
- );
- if (EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (ScsiDiskDevice);
- return Status;
- }
-
- ZeroMem (
- ScsiDiskDevice->SenseData,
- sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber
- );
-
- //
- // Retrive device information
- //
- MaxRetry = 2;
- for (Index = 0; Index < MaxRetry; Index++) {
- Status = ScsiDiskInquiryDevice (ScsiDiskDevice, &NeedRetry);
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (!NeedRetry) {
- gBS->FreePool (ScsiDiskDevice->SenseData);
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (ScsiDiskDevice);
- return EFI_DEVICE_ERROR;
- }
- }
- //
- // The second parameter "TRUE" means must
- // retrieve media capacity
- //
- Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);
- if (!EFI_ERROR (Status)) {
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Controller,
- &gEfiBlockIoProtocolGuid,
- &ScsiDiskDevice->BlkIo,
- NULL
- );
- }
-
- if (EFI_ERROR (Status)) {
- gBS->FreePool (ScsiDiskDevice->SenseData);
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (ScsiDiskDevice);
- return Status;
- }
-
- ScsiDiskDevice->ControllerNameTable = NULL;
- AddUnicodeString (
- "eng",
- gScsiDiskComponentName.SupportedLanguages,
- &ScsiDiskDevice->ControllerNameTable,
- (CHAR16 *) L"SCSI Disk Device"
- );
-
- return EFI_SUCCESS;
-
-}
-
-EFI_STATUS
-EFIAPI
-ScsiDiskDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
-/*++
-
- Routine Description:
-
- Arguments:
-
- Returns:
-
---*/
-// TODO: This - add argument and description to function comment
-// TODO: Controller - add argument and description to function comment
-// TODO: NumberOfChildren - add argument and description to function comment
-// TODO: ChildHandleBuffer - add argument and description to function comment
-// TODO: EFI_SUCCESS - add return value to function comment
-{
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- SCSI_DISK_DEV *ScsiDiskDevice;
- EFI_STATUS Status;
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiBlockIoProtocolGuid,
- (VOID **) &BlkIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlkIo);
- Status = gBS->UninstallProtocolInterface (
- Controller,
- &gEfiBlockIoProtocolGuid,
- &ScsiDiskDevice->BlkIo
- );
- if (!EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- ReleaseScsiDiskDeviceResources (ScsiDiskDevice);
-
- return EFI_SUCCESS;
- }
- //
- // errors met
- //
- return Status;
-}
-
-//
-// Block I/O Protocol Interface
-//
-
-EFI_STATUS
-EFIAPI
-ScsiDiskReset (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- This - TODO: add argument description
- ExtendedVerification - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- SCSI_DISK_DEV *ScsiDiskDevice;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
-
- Status = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
-
- if (!ExtendedVerification) {
- goto Done;
- }
-
- Status = ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
-
-Done:
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-ScsiDiskReadBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA LBA,
- IN UINTN BufferSize,
- OUT VOID *Buffer
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- This - TODO: add argument description
- MediaId - TODO: add argument description
- LBA - TODO: add argument description
- BufferSize - TODO: add argument description
- Buffer - TODO: add argument description
-
-Returns:
-
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_NO_MEDIA - TODO: Add description for return value
- EFI_MEDIA_CHANGED - TODO: Add description for return value
- EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
-
---*/
-{
- SCSI_DISK_DEV *ScsiDiskDevice;
- EFI_BLOCK_IO_MEDIA *Media;
- EFI_STATUS Status;
- UINTN BlockSize;
- UINTN NumberOfBlocks;
- BOOLEAN MediaChange;
- EFI_TPL OldTpl;
-
- MediaChange = FALSE;
- if (!Buffer) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (BufferSize == 0) {
- return EFI_SUCCESS;
- }
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
-
- if (!IsDeviceFixed (ScsiDiskDevice)) {
-
- Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
-
- if (MediaChange) {
- gBS->ReinstallProtocolInterface (
- ScsiDiskDevice->Handle,
- &gEfiBlockIoProtocolGuid,
- &ScsiDiskDevice->BlkIo,
- &ScsiDiskDevice->BlkIo
- );
- }
- }
- //
- // Get the intrinsic block size
- //
- Media = ScsiDiskDevice->BlkIo.Media;
- BlockSize = Media->BlockSize;
-
- NumberOfBlocks = BufferSize / BlockSize;
-
- if (!(Media->MediaPresent)) {
- Status = EFI_NO_MEDIA;
- goto Done;
- }
-
- if (MediaId != Media->MediaId) {
- Status = EFI_MEDIA_CHANGED;
- goto Done;
- }
-
- if (BufferSize % BlockSize != 0) {
- Status = EFI_BAD_BUFFER_SIZE;
- goto Done;
- }
-
- if (LBA > Media->LastBlock) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- //
- // if all the parameters are valid, then perform read sectors command
- // to transfer data from device to host.
- //
- Status = ScsiDiskReadSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);
-
-Done:
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-ScsiDiskWriteBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA LBA,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- This - TODO: add argument description
- MediaId - TODO: add argument description
- LBA - TODO: add argument description
- BufferSize - TODO: add argument description
- Buffer - TODO: add argument description
-
-Returns:
-
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_NO_MEDIA - TODO: Add description for return value
- EFI_MEDIA_CHANGED - TODO: Add description for return value
- EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
- EFI_INVALID_PARAMETER - TODO: Add description for return value
-
---*/
-{
- SCSI_DISK_DEV *ScsiDiskDevice;
- EFI_BLOCK_IO_MEDIA *Media;
- EFI_STATUS Status;
- UINTN BlockSize;
- UINTN NumberOfBlocks;
- BOOLEAN MediaChange;
- EFI_TPL OldTpl;
-
- MediaChange = FALSE;
- if (!Buffer) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (BufferSize == 0) {
- return EFI_SUCCESS;
- }
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
-
- if (!IsDeviceFixed (ScsiDiskDevice)) {
-
- Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
-
- if (MediaChange) {
- gBS->ReinstallProtocolInterface (
- ScsiDiskDevice->Handle,
- &gEfiBlockIoProtocolGuid,
- &ScsiDiskDevice->BlkIo,
- &ScsiDiskDevice->BlkIo
- );
- }
- }
- //
- // Get the intrinsic block size
- //
- Media = ScsiDiskDevice->BlkIo.Media;
- BlockSize = Media->BlockSize;
-
- NumberOfBlocks = BufferSize / BlockSize;
-
- if (!(Media->MediaPresent)) {
- Status = EFI_NO_MEDIA;
- goto Done;
- }
-
- if (MediaId != Media->MediaId) {
- Status = EFI_MEDIA_CHANGED;
- goto Done;
- }
-
- if (BufferSize % BlockSize != 0) {
- Status = EFI_BAD_BUFFER_SIZE;
- goto Done;
- }
-
- if (LBA > Media->LastBlock) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
- //
- // if all the parameters are valid, then perform read sectors command
- // to transfer data from device to host.
- //
- Status = ScsiDiskWriteSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);
-
-Done:
- gBS->RestoreTPL (OldTpl);
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-ScsiDiskFlushBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- This - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- //
- // return directly
- //
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ScsiDiskDetectMedia (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN MustReadCapacity,
- BOOLEAN *MediaChange
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- MustReadCapacity - TODO: add argument description
- MediaChange - TODO: add argument description
-
-Returns:
-
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- EFI_STATUS Status;
- EFI_STATUS ReadCapacityStatus;
- EFI_SCSI_SENSE_DATA *SenseData;
- UINTN NumberOfSenseKeys;
- BOOLEAN NeedRetry;
- BOOLEAN NeedReadCapacity;
- UINT8 Index;
- UINT8 MaxRetry;
- EFI_BLOCK_IO_MEDIA OldMedia;
- UINTN Action;
-
- Status = EFI_SUCCESS;
- ReadCapacityStatus = EFI_SUCCESS;
- SenseData = NULL;
- NumberOfSenseKeys = 0;
- NeedReadCapacity = FALSE;
- CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));
- // OldMedia = *(ScsiDiskDevice->BlkIo.Media);
-
- *MediaChange = FALSE;
-
- MaxRetry = 3;
- for (Index = 0; Index < MaxRetry; Index++) {
- Status = ScsiDiskTestUnitReady (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys
- );
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (!NeedRetry) {
- return Status;
- }
- }
-
- if ((Index == MaxRetry) && EFI_ERROR (Status)) {
- 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 {
- NeedReadCapacity = TRUE;
- }
-
- //
- // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,
- // retrieve capacity via Read Capacity command
- //
- if (NeedReadCapacity || MustReadCapacity) {
-
- //
- // retrieve media information
- //
- MaxRetry = 3;
- for (Index = 0; Index < MaxRetry; Index++) {
-
- ReadCapacityStatus = ScsiDiskReadCapacity (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys
- );
- if (EFI_ERROR (ReadCapacityStatus) && !NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
- //
- // analyze sense key to action
- //
- Status = DetectMediaParsingSenseKeys (
- ScsiDiskDevice,
- SenseData,
- NumberOfSenseKeys,
- &Action
- );
- //
- // if Status is error, it may indicate crisis error,
- // so return without retry.
- //
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- 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;
- }
- }
-
- if (ScsiDiskDevice->BlkIo.Media->MediaId != OldMedia.MediaId) {
- //
- // Media change information got from the device
- //
- *MediaChange = TRUE;
- }
-
- if (ScsiDiskDevice->BlkIo.Media->ReadOnly != OldMedia.ReadOnly) {
- *MediaChange = TRUE;
- ScsiDiskDevice->BlkIo.Media->MediaId += 1;
- }
-
- if (ScsiDiskDevice->BlkIo.Media->BlockSize != OldMedia.BlockSize) {
- *MediaChange = TRUE;
- ScsiDiskDevice->BlkIo.Media->MediaId += 1;
- }
-
- if (ScsiDiskDevice->BlkIo.Media->LastBlock != OldMedia.LastBlock) {
- *MediaChange = TRUE;
- ScsiDiskDevice->BlkIo.Media->MediaId += 1;
- }
-
- if (ScsiDiskDevice->BlkIo.Media->MediaPresent != OldMedia.MediaPresent) {
- if (ScsiDiskDevice->BlkIo.Media->MediaPresent) {
- //
- // when change from no media to media present, reset the MediaId to 1.
- //
- ScsiDiskDevice->BlkIo.Media->MediaId = 1;
- } else {
- //
- // when no media, reset the MediaId to zero.
- //
- ScsiDiskDevice->BlkIo.Media->MediaId = 0;
- }
-
- *MediaChange = TRUE;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ScsiDiskInquiryDevice (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- NeedRetry - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
-
---*/
-{
- UINT32 InquiryDataLength;
- UINT8 SenseDataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
- EFI_SCSI_SENSE_DATA *SenseDataArray;
- UINTN NumberOfSenseKeys;
- EFI_STATUS Status;
- UINT8 MaxRetry;
- UINT8 Index;
-
- InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
- SenseDataLength = 0;
-
- Status = SubmitInquiryCommand (
- ScsiDiskDevice->ScsiIo,
- EfiScsiStallSeconds (1),
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- (VOID *) &(ScsiDiskDevice->InquiryData),
- &InquiryDataLength,
- FALSE
- );
- if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- ParseInquiryData (ScsiDiskDevice);
- return EFI_SUCCESS;
- } else if (Status == EFI_NOT_READY) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
- //
- // go ahead to check HostAdapterStatus and TargetStatus
- // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
- //
- Status = CheckHostAdapterStatus (HostAdapterStatus);
- if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- //
- // reset the scsi channel
- //
- ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- Status = CheckTargetStatus (TargetStatus);
- if (Status == EFI_NOT_READY) {
- //
- // reset the scsi device
- //
- ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- //
- // if goes here, meant SubmitInquiryCommand() failed.
- // if ScsiDiskRequestSenseKeys() succeeds at last,
- // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)
- //
- MaxRetry = 3;
- for (Index = 0; Index < MaxRetry; Index++) {
-
- Status = ScsiDiskRequestSenseKeys (
- ScsiDiskDevice,
- NeedRetry,
- &SenseDataArray,
- &NumberOfSenseKeys,
- TRUE
- );
- if (!EFI_ERROR (Status)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- }
-
- if (!*NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
- }
- //
- // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
- // set *NeedRetry = FALSE to avoid the outside caller try again.
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
-}
-
-EFI_STATUS
-ScsiDiskTestUnitReady (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry,
- EFI_SCSI_SENSE_DATA **SenseDataArray,
- UINTN *NumberOfSenseKeys
- )
-// TODO: function comment should start with '/*++'
-/*
- When Test Unit Ready command succeeds,
- retrieve Sense Keys via Request Sense;
- When Test Unit Ready command encounters any error caused by host adapter or
- target, return error without retrieving Sense Keys.
-*/
-// TODO: function comment should end with '--*/'
-// TODO: function comment is missing 'Routine Description:'
-// TODO: function comment is missing 'Arguments:'
-// TODO: function comment is missing 'Returns:'
-// TODO: ScsiDiskDevice - add argument and description to function comment
-// TODO: NeedRetry - add argument and description to function comment
-// TODO: SenseDataArray - add argument and description to function comment
-// TODO: NumberOfSenseKeys - add argument and description to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_SUCCESS - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-{
- EFI_STATUS Status;
- UINT8 SenseDataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
- UINT8 Index;
- UINT8 MaxRetry;
-
- SenseDataLength = 0;
- *NumberOfSenseKeys = 0;
-
- //
- // Parameter 3 and 4: do not require sense data, retrieve it when needed.
- //
- Status = SubmitTestUnitReadyCommand (
- ScsiDiskDevice->ScsiIo,
- EfiScsiStallSeconds (1),
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus
- );
- if (Status == EFI_NOT_READY) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
- //
- // go ahead to check HostAdapterStatus and TargetStatus
- //
- Status = CheckHostAdapterStatus (HostAdapterStatus);
- if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- //
- // reset the scsi channel
- //
- ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- Status = CheckTargetStatus (TargetStatus);
- if (Status == EFI_NOT_READY) {
- //
- // reset the scsi device
- //
- ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- MaxRetry = 3;
- for (Index = 0; Index < MaxRetry; Index++) {
-
- Status = ScsiDiskRequestSenseKeys (
- ScsiDiskDevice,
- NeedRetry,
- SenseDataArray,
- NumberOfSenseKeys,
- FALSE
- );
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- }
-
- if (!*NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
- }
- //
- // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
- // set *NeedRetry = FALSE to avoid the outside caller try again.
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
-}
-
-EFI_STATUS
-DetectMediaParsingSenseKeys (
- SCSI_DISK_DEV *ScsiDiskDevice,
- EFI_SCSI_SENSE_DATA *SenseData,
- UINTN NumberOfSenseKeys,
- UINTN *Action
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- SenseData - TODO: add argument description
- NumberOfSenseKeys - TODO: add argument description
- Action - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- BOOLEAN RetryLater;
-
- //
- // Default is to read capacity, unless..
- //
- *Action = ACTION_READ_CAPACITY;
-
- if (NumberOfSenseKeys == 0) {
- *Action = ACTION_NO_ACTION;
- return EFI_SUCCESS;
- }
-
- if (!ScsiDiskHaveSenseKey (SenseData, NumberOfSenseKeys)) {
- //
- // No Sense Key returned from last submitted command
- //
- *Action = ACTION_NO_ACTION;
- return EFI_SUCCESS;
- }
-
- if (ScsiDiskIsNoMedia (SenseData, NumberOfSenseKeys)) {
- ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
- ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
- *Action = ACTION_NO_ACTION;
- return EFI_SUCCESS;
- }
-
- if (ScsiDiskIsMediaChange (SenseData, NumberOfSenseKeys)) {
- ScsiDiskDevice->BlkIo.Media->MediaId++;
- return EFI_SUCCESS;
- }
-
- if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {
- ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
- ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
- return EFI_DEVICE_ERROR;
- }
-
- if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {
- return EFI_DEVICE_ERROR;
- }
-
- if (!ScsiDiskIsDriveReady (SenseData, NumberOfSenseKeys, &RetryLater)) {
- if (RetryLater) {
- *Action = ACTION_RETRY_COMMAND_LATER;
- return EFI_SUCCESS;
- }
-
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ScsiDiskReadCapacity (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry,
- EFI_SCSI_SENSE_DATA **SenseDataArray,
- UINTN *NumberOfSenseKeys
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- NeedRetry - TODO: add argument description
- SenseDataArray - TODO: add argument description
- NumberOfSenseKeys - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
-
---*/
-{
- EFI_SCSI_DISK_CAPACITY_DATA CapacityData;
- UINT32 DataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
- EFI_STATUS CommandStatus;
- EFI_STATUS Status;
- UINT8 Index;
- UINT8 MaxRetry;
- UINT8 SenseDataLength;
-
- SenseDataLength = 0;
- ZeroMem (&CapacityData, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));
- DataLength = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);
-
- *NumberOfSenseKeys = 0;
- *NeedRetry = FALSE;
- //
- // submit Read Capacity Command. in this call,not request sense data
- //
- CommandStatus = SubmitReadCapacityCommand (
- ScsiDiskDevice->ScsiIo,
- EfiScsiStallSeconds (1),
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- (VOID *) &CapacityData,
- &DataLength,
- FALSE
- );
- if (CommandStatus == EFI_SUCCESS) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- GetMediaInfo (ScsiDiskDevice, &CapacityData);
- return EFI_SUCCESS;
- } else if (CommandStatus == EFI_NOT_READY) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if ((CommandStatus == EFI_INVALID_PARAMETER) || (CommandStatus == EFI_UNSUPPORTED)) {
- //
- // no need to check HostAdapterStatus and TargetStatus
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
- //
- // go ahead to check HostAdapterStatus and TargetStatus
- // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)
- //
-
- Status = CheckHostAdapterStatus (HostAdapterStatus);
- if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- //
- // reset the scsi channel
- //
- ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- Status = CheckTargetStatus (TargetStatus);
- if (Status == EFI_NOT_READY) {
- //
- // reset the scsi device
- //
- ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
-
- //
- // if goes here, meant SubmitReadCapacityCommand() failed.
- // if ScsiDiskRequestSenseKeys() succeeds at last,
- // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)
- //
- MaxRetry = 3;
- for (Index = 0; Index < MaxRetry; Index++) {
-
- Status = ScsiDiskRequestSenseKeys (
- ScsiDiskDevice,
- NeedRetry,
- SenseDataArray,
- NumberOfSenseKeys,
- TRUE
- );
- if (!EFI_ERROR (Status)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- }
-
- if (!*NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
- }
- //
- // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
- // set *NeedRetry = FALSE to avoid the outside caller try again.
- //
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
-}
-
-EFI_STATUS
-CheckHostAdapterStatus (
- UINT8 HostAdapterStatus
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- HostAdapterStatus - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
- EFI_TIMEOUT - TODO: Add description for return value
- EFI_NOT_READY - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- switch (HostAdapterStatus) {
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK:
- return EFI_SUCCESS;
-
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND:
- return EFI_TIMEOUT;
-
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET:
- return EFI_NOT_READY;
-
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE:
- case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR:
- return EFI_DEVICE_ERROR;
-
- default:
- return EFI_SUCCESS;
- }
-}
-
-EFI_STATUS
-CheckTargetStatus (
- UINT8 TargetStatus
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- TargetStatus - TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - TODO: Add description for return value
- EFI_NOT_READY - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- switch (TargetStatus) {
- case EFI_SCSI_IO_STATUS_TARGET_GOOD:
- case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION:
- case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET:
- return EFI_SUCCESS;
-
- case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE:
- case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET:
- case EFI_SCSI_IO_STATUS_TARGET_BUSY:
- case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED:
- case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL:
- return EFI_NOT_READY;
-
- case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT:
- return EFI_DEVICE_ERROR;
- break;
-
- default:
- return EFI_SUCCESS;
- }
-}
-
-EFI_STATUS
-ScsiDiskRequestSenseKeys (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry,
- EFI_SCSI_SENSE_DATA **SenseDataArray,
- UINTN *NumberOfSenseKeys,
- BOOLEAN AskResetIfError
- )
-// TODO: function comment should start with '/*++'
-/*
- Retrieve all sense keys from the device.
- When encountering error during the process,
- if retrieve sense keys before error encounterred,
- return the sense keys with return status set to EFI_SUCCESS,
- and NeedRetry set to FALSE; otherwize, return the proper return
- status.
-*/
-// TODO: function comment should end with '--*/'
-// TODO: function comment is missing 'Routine Description:'
-// TODO: function comment is missing 'Arguments:'
-// TODO: function comment is missing 'Returns:'
-// TODO: ScsiDiskDevice - add argument and description to function comment
-// TODO: NeedRetry - add argument and description to function comment
-// TODO: SenseDataArray - add argument and description to function comment
-// TODO: NumberOfSenseKeys - add argument and description to function comment
-// TODO: AskResetIfError - add argument and description to function comment
-// TODO: EFI_SUCCESS - add return value to function comment
-// TODO: EFI_DEVICE_ERROR - add return value to function comment
-// TODO: EFI_SUCCESS - add return value to function comment
-{
- EFI_SCSI_SENSE_DATA *PtrSenseData;
- UINT8 SenseDataLength;
- BOOLEAN SenseReq;
- EFI_STATUS Status;
- EFI_STATUS FallStatus;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
-
- FallStatus = EFI_SUCCESS;
- SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);
-
- ZeroMem (
- ScsiDiskDevice->SenseData,
- sizeof (EFI_SCSI_SENSE_DATA) * (ScsiDiskDevice->SenseDataNumber)
- );
-
- *NumberOfSenseKeys = 0;
- *SenseDataArray = ScsiDiskDevice->SenseData;
- PtrSenseData = ScsiDiskDevice->SenseData;
-
- for (SenseReq = TRUE; SenseReq;) {
-
- Status = SubmitRequestSenseCommand (
- ScsiDiskDevice->ScsiIo,
- EfiScsiStallSeconds (2),
- PtrSenseData,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus
- );
- if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {
- FallStatus = EFI_SUCCESS;
- } else if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
- *NeedRetry = TRUE;
- FallStatus = EFI_DEVICE_ERROR;
- } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {
- *NeedRetry = FALSE;
- FallStatus = EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
- if (AskResetIfError) {
- ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
- }
-
- FallStatus = EFI_DEVICE_ERROR;
- }
-
- if (EFI_ERROR (FallStatus)) {
- if (*NumberOfSenseKeys != 0) {
- *NeedRetry = FALSE;
- return EFI_SUCCESS;
- } else {
- return EFI_DEVICE_ERROR;
- }
- }
-
- (*NumberOfSenseKeys) += 1;
-
- //
- // no more sense key or number of sense keys exceeds predefined,
- // skip the loop.
- //
- if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
- (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber)) {
- SenseReq = FALSE;
- }
-
- PtrSenseData += 1;
-
- }
-
- return EFI_SUCCESS;
-}
-
-VOID
-GetMediaInfo (
- SCSI_DISK_DEV *ScsiDiskDevice,
- EFI_SCSI_DISK_CAPACITY_DATA *Capacity
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- Capacity - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity->LastLba3 << 24) |
- (Capacity->LastLba2 << 16) |
- (Capacity->LastLba1 << 8) |
- Capacity->LastLba0;
-
- ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;
- ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity->BlockSize3 << 24) |
- (Capacity->BlockSize2 << 16) |
- (Capacity->BlockSize1 << 8) |
- Capacity->BlockSize0;
- if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {
- ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;
- }
-
- if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_CDROM) {
- ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;
- }
-}
-
-VOID
-ParseInquiryData (
- SCSI_DISK_DEV *ScsiDiskDevice
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- ScsiDiskDevice->FixedDevice = (BOOLEAN) (ScsiDiskDevice->InquiryData.RMB ? 0 : 1);
- ScsiDiskDevice->BlkIoMedia.RemovableMedia = (BOOLEAN) (!ScsiDiskDevice->FixedDevice);
-}
-
-EFI_STATUS
-ScsiDiskReadSectors (
- SCSI_DISK_DEV *ScsiDiskDevice,
- VOID *Buffer,
- EFI_LBA Lba,
- UINTN NumberOfBlocks
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- Buffer - TODO: add argument description
- Lba - TODO: add argument description
- NumberOfBlocks - TODO: add argument description
-
-Returns:
-
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- UINTN BlocksRemaining;
- UINT32 Lba32;
- UINT8 *PtrBuffer;
- UINT32 BlockSize;
- UINT32 ByteCount;
- UINT32 MaxBlock;
- UINT32 SectorCount;
- UINT64 Timeout;
- EFI_STATUS Status;
- UINT8 Index;
- UINT8 MaxRetry;
- BOOLEAN NeedRetry;
- EFI_SCSI_SENSE_DATA *SenseData;
- UINTN NumberOfSenseKeys;
-
- SenseData = NULL;
- NumberOfSenseKeys = 0;
-
- Status = EFI_SUCCESS;
-
- BlocksRemaining = NumberOfBlocks;
- BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
- //
- // limit the data bytes that can be transferred by one Read(10) Command
- //
- MaxBlock = 65536;
-
- PtrBuffer = Buffer;
- Lba32 = (UINT32) Lba;
-
- while (BlocksRemaining > 0) {
-
- if (BlocksRemaining <= MaxBlock) {
-
- SectorCount = (UINT16) BlocksRemaining;
- } else {
-
- SectorCount = MaxBlock;
- }
-
- ByteCount = SectorCount * BlockSize;
- Timeout = EfiScsiStallSeconds (2);
-
- MaxRetry = 2;
- for (Index = 0; Index < MaxRetry; Index++) {
-
- Status = ScsiDiskRead10 (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys,
- Timeout,
- PtrBuffer,
- &ByteCount,
- Lba32,
- SectorCount
- );
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (!NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
-
- }
-
- if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // actual transferred sectors
- //
- SectorCount = ByteCount / BlockSize;
-
- Lba32 += SectorCount;
- PtrBuffer = PtrBuffer + SectorCount * BlockSize;
- BlocksRemaining -= SectorCount;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ScsiDiskWriteSectors (
- SCSI_DISK_DEV *ScsiDiskDevice,
- VOID *Buffer,
- EFI_LBA Lba,
- UINTN NumberOfBlocks
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- Buffer - TODO: add argument description
- Lba - TODO: add argument description
- NumberOfBlocks - TODO: add argument description
-
-Returns:
-
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_DEVICE_ERROR - TODO: Add description for return value
- EFI_SUCCESS - TODO: Add description for return value
-
---*/
-{
- UINTN BlocksRemaining;
- UINT32 Lba32;
- UINT8 *PtrBuffer;
- UINT32 BlockSize;
- UINT32 ByteCount;
- UINT32 MaxBlock;
- UINT32 SectorCount;
- UINT64 Timeout;
- EFI_STATUS Status;
- UINT8 Index;
- UINT8 MaxRetry;
- BOOLEAN NeedRetry;
- EFI_SCSI_SENSE_DATA *SenseData;
- UINTN NumberOfSenseKeys;
-
- SenseData = NULL;
- NumberOfSenseKeys = 0;
-
- Status = EFI_SUCCESS;
-
- BlocksRemaining = NumberOfBlocks;
- BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
- //
- // limit the data bytes that can be transferred by one Write(10) Command
- //
- MaxBlock = 65536;
-
- PtrBuffer = Buffer;
- Lba32 = (UINT32) Lba;
-
- while (BlocksRemaining > 0) {
-
- if (BlocksRemaining <= MaxBlock) {
-
- SectorCount = (UINT16) BlocksRemaining;
- } else {
-
- SectorCount = MaxBlock;
- }
-
- ByteCount = SectorCount * BlockSize;
- Timeout = EfiScsiStallSeconds (2);
- MaxRetry = 2;
- for (Index = 0; Index < MaxRetry; Index++) {
- Status = ScsiDiskWrite10 (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys,
- Timeout,
- PtrBuffer,
- &ByteCount,
- Lba32,
- SectorCount
- );
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (!NeedRetry) {
- return EFI_DEVICE_ERROR;
- }
- }
-
- if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {
- return EFI_DEVICE_ERROR;
- }
- //
- // actual transferred sectors
- //
- SectorCount = ByteCount / BlockSize;
-
- Lba32 += SectorCount;
- PtrBuffer = PtrBuffer + SectorCount * BlockSize;
- BlocksRemaining -= SectorCount;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ScsiDiskRead10 (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry,
- EFI_SCSI_SENSE_DATA **SenseDataArray,
- UINTN *NumberOfSenseKeys,
- UINT64 Timeout,
- UINT8 *DataBuffer,
- UINT32 *DataLength,
- UINT32 StartLba,
- UINT32 SectorSize
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- NeedRetry - TODO: add argument description
- SenseDataArray - TODO: add argument description
- NumberOfSenseKeys - TODO: add argument description
- Timeout - TODO: add argument description
- DataBuffer - TODO: add argument description
- DataLength - TODO: add argument description
- StartLba - TODO: add argument description
- SectorSize - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- UINT8 SenseDataLength;
- EFI_STATUS Status;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
-
- *NeedRetry = FALSE;
- *NumberOfSenseKeys = 0;
- SenseDataLength = 0;
- Status = SubmitRead10Command (
- ScsiDiskDevice->ScsiIo,
- Timeout,
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- DataBuffer,
- DataLength,
- StartLba,
- SectorSize
- );
- return Status;
-}
-
-EFI_STATUS
-ScsiDiskWrite10 (
- SCSI_DISK_DEV *ScsiDiskDevice,
- BOOLEAN *NeedRetry,
- EFI_SCSI_SENSE_DATA **SenseDataArray,
- UINTN *NumberOfSenseKeys,
- UINT64 Timeout,
- UINT8 *DataBuffer,
- UINT32 *DataLength,
- UINT32 StartLba,
- UINT32 SectorSize
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
- NeedRetry - TODO: add argument description
- SenseDataArray - TODO: add argument description
- NumberOfSenseKeys - TODO: add argument description
- Timeout - TODO: add argument description
- DataBuffer - TODO: add argument description
- DataLength - TODO: add argument description
- StartLba - TODO: add argument description
- SectorSize - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_STATUS Status;
- UINT8 SenseDataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
-
- *NeedRetry = FALSE;
- *NumberOfSenseKeys = 0;
- SenseDataLength = 0;
- Status = SubmitWrite10Command (
- ScsiDiskDevice->ScsiIo,
- Timeout,
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- DataBuffer,
- DataLength,
- StartLba,
- SectorSize
- );
- return Status;
-}
-
-BOOLEAN
-ScsiDiskIsNoMedia (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsNoMedia;
-
- IsNoMedia = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- //
- // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),
- // Additional Sense Code is ASC_NO_MEDIA (0x3A)
- //
- if ((SensePtr->Sense_Key == EFI_SCSI_SK_NOT_READY) &&
- (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_NO_MEDIA)) {
- IsNoMedia = TRUE;
- }
-
- SensePtr++;
- }
-
- return IsNoMedia;
-}
-
-BOOLEAN
-ScsiDiskIsMediaError (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsError;
-
- IsError = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- switch (SensePtr->Sense_Key) {
-
- case EFI_SCSI_SK_MEDIUM_ERROR:
- //
- // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)
- //
- switch (SensePtr->Addnl_Sense_Code) {
-
- //
- // fall through
- //
- case EFI_SCSI_ASC_MEDIA_ERR1:
-
- //
- // fall through
- //
- case EFI_SCSI_ASC_MEDIA_ERR2:
-
- //
- // fall through
- //
- case EFI_SCSI_ASC_MEDIA_ERR3:
- case EFI_SCSI_ASC_MEDIA_ERR4:
- IsError = TRUE;
- break;
-
- default:
- break;
- }
-
- break;
-
- case EFI_SCSI_SK_NOT_READY:
- //
- // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
- //
- switch (SensePtr->Addnl_Sense_Code) {
- //
- // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)
- //
- case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN:
- IsError = TRUE;
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- SensePtr++;
- }
-
- return IsError;
-}
-
-BOOLEAN
-ScsiDiskIsHardwareError (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsError;
-
- IsError = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- //
- // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)
- //
- if (SensePtr->Sense_Key == EFI_SCSI_SK_HARDWARE_ERROR) {
- IsError = TRUE;
- }
-
- SensePtr++;
- }
-
- return IsError;
-}
-
-BOOLEAN
-ScsiDiskIsMediaChange (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsMediaChanged;
-
- IsMediaChanged = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
- //
- // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),
- // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)
- //
- if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&
- (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_MEDIA_CHANGE)) {
- IsMediaChanged = TRUE;
- }
-
- SensePtr++;
- }
-
- return IsMediaChanged;
-}
-
-BOOLEAN
-ScsiDiskIsResetBefore (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsResetBefore;
-
- IsResetBefore = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- //
- // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)
- // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)
- //
- if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&
- (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_RESET)) {
- IsResetBefore = TRUE;
- }
-
- SensePtr++;
- }
-
- return IsResetBefore;
-}
-
-BOOLEAN
-ScsiDiskIsDriveReady (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts,
- OUT BOOLEAN *RetryLater
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
- RetryLater - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN IsReady;
-
- IsReady = TRUE;
- *RetryLater = FALSE;
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- switch (SensePtr->Sense_Key) {
-
- case EFI_SCSI_SK_NOT_READY:
- //
- // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
- //
- switch (SensePtr->Addnl_Sense_Code) {
- case EFI_SCSI_ASC_NOT_READY:
- //
- // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)
- //
- switch (SensePtr->Addnl_Sense_Code_Qualifier) {
- case EFI_SCSI_ASCQ_IN_PROGRESS:
- //
- // Additional Sense Code Qualifier is
- // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)
- //
- IsReady = FALSE;
- *RetryLater = TRUE;
- break;
-
- default:
- IsReady = FALSE;
- *RetryLater = FALSE;
- break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- SensePtr++;
- }
-
- return IsReady;
-}
-
-BOOLEAN
-ScsiDiskHaveSenseKey (
- IN EFI_SCSI_SENSE_DATA *SenseData,
- IN UINTN SenseCounts
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- SenseData - TODO: add argument description
- SenseCounts - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- EFI_SCSI_SENSE_DATA *SensePtr;
- UINTN Index;
- BOOLEAN HaveSenseKey;
-
- if (SenseCounts == 0) {
- HaveSenseKey = FALSE;
- } else {
- HaveSenseKey = TRUE;
- }
-
- SensePtr = SenseData;
-
- for (Index = 0; Index < SenseCounts; Index++) {
-
- //
- // Sense Key is SK_NO_SENSE (0x0)
- //
- if ((SensePtr->Sense_Key == EFI_SCSI_SK_NO_SENSE) &&
- (Index == 0)) {
- HaveSenseKey = FALSE;
- }
-
- SensePtr++;
- }
-
- return HaveSenseKey;
-}
-
-VOID
-ReleaseScsiDiskDeviceResources (
- IN SCSI_DISK_DEV *ScsiDiskDevice
- )
-/*++
-
-Routine Description:
-
- TODO: Add function description
-
-Arguments:
-
- ScsiDiskDevice - TODO: add argument description
-
-Returns:
-
- TODO: add return values
-
---*/
-{
- if (ScsiDiskDevice == NULL) {
- return ;
- }
-
- if (ScsiDiskDevice->SenseData != NULL) {
- gBS->FreePool (ScsiDiskDevice->SenseData);
- ScsiDiskDevice->SenseData = NULL;
- }
-
- if (ScsiDiskDevice->ControllerNameTable != NULL) {
- FreeUnicodeStringTable (ScsiDiskDevice->ControllerNameTable);
- ScsiDiskDevice->ControllerNameTable = NULL;
- }
-
- gBS->FreePool (ScsiDiskDevice);
-
- ScsiDiskDevice = NULL;
-}