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