--- /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
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/ScsiIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/DriverBinding.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ScsiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\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
+/**\r
+ The user Entry Point for module ScsiDisk. The user code starts with this function.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeScsiDisk(\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallAllDriverProtocols (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gScsiDiskDriverBinding,\r
+ ImageHandle,\r
+ &gScsiDiskComponentName,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+ return Status;\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
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, 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.h\r
+\r
+Abstract:\r
+ \r
+ Header file for SCSI Disk Driver.\r
+\r
+--*/\r
+\r
+#ifndef _SCSI_DISK_H\r
+#define _SCSI_DISK_H\r
+\r
+\r
+#include <IndustryStandard/scsi.h>\r
+\r
+#define IsDeviceFixed(a) (a)->FixedDevice ? 1 : 0\r
+\r
+#define SCSI_DISK_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'c', 'd', 'k')\r
+\r
+typedef struct {\r
+ UINT32 Signature;\r
+\r
+ EFI_HANDLE Handle;\r
+\r
+ EFI_BLOCK_IO_PROTOCOL BlkIo;\r
+ EFI_BLOCK_IO_MEDIA BlkIoMedia;\r
+ EFI_SCSI_IO_PROTOCOL *ScsiIo;\r
+ UINT8 DeviceType;\r
+ BOOLEAN FixedDevice;\r
+ UINT16 Reserved;\r
+\r
+ EFI_SCSI_SENSE_DATA *SenseData;\r
+ UINTN SenseDataNumber;\r
+ EFI_SCSI_INQUIRY_DATA InquiryData;\r
+\r
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
+\r
+} SCSI_DISK_DEV;\r
+\r
+#define SCSI_DISK_DEV_FROM_THIS(a) CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gScsiDiskComponentName;\r
+//\r
+// action code used in detect media process\r
+//\r
+#define ACTION_NO_ACTION 0x00\r
+#define ACTION_READ_CAPACITY 0x01\r
+#define ACTION_RETRY_COMMAND_LATER 0x02\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
+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
+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
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiDiskComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiDiskComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\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
+\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ScsiDiskDetectMedia (\r
+ SCSI_DISK_DEV *ScsiDiskDevice,\r
+ BOOLEAN MustReadCap,\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
+ MustReadCap - TODO: add argument description\r
+ MediaChange - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\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
+/*++\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\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
+ TODO: add return values\r
+\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
+/*++\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
+ AskResetIfError - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\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
+\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
+ TODO: add return values\r
+\r
+--*/\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
+ TODO: add return values\r
+\r
+--*/\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\r
+BOOLEAN\r
+ScsiDiskIsDriveReady (\r
+ IN EFI_SCSI_SENSE_DATA *SenseData,\r
+ IN UINTN SenseCounts,\r
+ OUT BOOLEAN *NeedRetry\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
+ NeedRetry - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ TODO: add return values\r
+\r
+--*/\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
+\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
+\r
+#endif\r