Add ScsiDiskDxe driver for Nt32Pkg
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 29 Jun 2007 03:44:58 +0000 (03:44 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 29 Jun 2007 03:44:58 +0000 (03:44 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2879 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ComponentName.c [new file with mode: 0644]
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c [new file with mode: 0644]
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h [new file with mode: 0644]
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf [new file with mode: 0644]
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.msa [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dsc
Nt32Pkg/Nt32.dsc

diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ComponentName.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..24adbe9
--- /dev/null
@@ -0,0 +1,202 @@
+/*++\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
+  ComponentName.c\r
+\r
+Abstract:\r
+\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
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gScsiDiskComponentName = {\r
+  ScsiDiskComponentNameGetDriverName,\r
+  ScsiDiskComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mScsiDiskDriverNameTable[] = {\r
+  { "eng", (CHAR16 *) L"Scsi Disk Driver" },\r
+  { NULL , NULL }\r
+};\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
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  Arguments:\r
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    Language   - A pointer to a three character ISO 639-2 language identifier.\r
+                 This is the language of the driver name that that the caller \r
+                 is requesting, and it must match one of the languages specified\r
+                 in SupportedLanguages.  The number of languages supported by a \r
+                 driver is up to the driver writer.\r
+    DriverName - A pointer to the Unicode string to return.  This Unicode string\r
+                 is the name of the driver specified by This in the language \r
+                 specified by Language.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This\r
+                            and the language specified by Language was returned \r
+                            in DriverName.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - DriverName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gScsiDiskComponentName.SupportedLanguages,\r
+          mScsiDiskDriverNameTable,\r
+          DriverName\r
+          );\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
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the controller\r
+    that is being managed by an EFI Driver.\r
+\r
+  Arguments:\r
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    ControllerHandle - The handle of a controller that the driver specified by \r
+                       This is managing.  This handle specifies the controller \r
+                       whose name is to be returned.\r
+    ChildHandle      - The handle of the child controller to retrieve the name \r
+                       of.  This is an optional parameter that may be NULL.  It \r
+                       will be NULL for device drivers.  It will also be NULL \r
+                       for a bus drivers that wish to retrieve the name of the \r
+                       bus controller.  It will not be NULL for a bus driver \r
+                       that wishes to retrieve the name of a child controller.\r
+    Language         - A pointer to a three character ISO 639-2 language \r
+                       identifier.  This is the language of the controller name \r
+                       that that the caller is requesting, and it must match one\r
+                       of the languages specified in SupportedLanguages.  The \r
+                       number of languages supported by a driver is up to the \r
+                       driver writer.\r
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode\r
+                       string is the name of the controller specified by \r
+                       ControllerHandle and ChildHandle in the language \r
+                       specified by Language from the point of view of the \r
+                       driver specified by This. \r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the user readable name in the\r
+                            language specified by Language for the driver \r
+                            specified by This was returned in DriverName.\r
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid \r
+                            EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This is not currently \r
+                            managing the controller specified by \r
+                            ControllerHandle and ChildHandle.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  SCSI_DISK_DEV         *ScsiDiskDevice;\r
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+\r
+  //\r
+  // This is a device driver, so ChildHandle must be NULL.\r
+  //\r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // Make sure this driver is currently managing ControllerHandle\r
+  //\r
+  Status = EfiTestManagedDevice (\r
+             ControllerHandle,\r
+             gScsiDiskDriverBinding.DriverBindingHandle,\r
+             &gEfiScsiIoProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Get the device context\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  (VOID **) &BlockIo,\r
+                  gScsiDiskDriverBinding.DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlockIo);\r
+\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gScsiDiskComponentName.SupportedLanguages,\r
+          ScsiDiskDevice->ControllerNameTable,\r
+          ControllerName\r
+          );\r
+\r
+}\r
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
new file mode 100644 (file)
index 0000000..e85f99b
--- /dev/null
@@ -0,0 +1,2412 @@
+/*++\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
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
new file mode 100644 (file)
index 0000000..675c643
--- /dev/null
@@ -0,0 +1,774 @@
+/*++\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
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
new file mode 100644 (file)
index 0000000..fa7cca0
--- /dev/null
@@ -0,0 +1,100 @@
+#/** @file\r
+# Component description file for Scsi Disk module.Revision History\r
+#\r
+# Scsi Disk driver. This driver detected the Scsi disk media and export block io protocol\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\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
+#  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
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ScsiDisk\r
+  FILE_GUID                      = 0A66E322-3740-4cce-AD62-BD172CECCA35\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00010010\r
+\r
+  ENTRY_POINT                    = InitializeScsiDisk\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+#  DRIVER_BINDING                =  gScsiDiskDriverBinding                       \r
+#  COMPONENT_NAME                =  gScsiDiskComponentName                       \r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  ComponentName.c\r
+  ScsiDisk.c\r
+  ScsiDisk.h\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg/Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  ScsiLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiBlockIoProtocolGuid                       # PROTOCOL BY_START\r
+  gEfiScsiIoProtocolGuid                        # PROTOCOL TO_START\r
+\r
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.msa b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.msa
new file mode 100644 (file)
index 0000000..eb722a2
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>ScsiDisk</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>0A66E322-3740-4cce-AD62-BD172CECCA35</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for Scsi Disk module.Revision History</Abstract>\r
+    <Description>Scsi Disk driver. This driver detected the Scsi disk media and export block io protocol</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>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
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>ScsiDisk</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverModelLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>EdkScsiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>ScsiDisk.h</Filename>\r
+    <Filename>ScsiDisk.c</Filename>\r
+    <Filename>ComponentName.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiScsiIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00010010</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <DriverBinding>gScsiDiskDriverBinding</DriverBinding>\r
+      <ComponentName>gScsiDiskComponentName</ComponentName>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
index baf274a..d7c468c 100644 (file)
   ${WORKSPACE}/MdeModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.inf\r
   ${WORKSPACE}/MdeModulePkg/Universal/WatchDogTimerDxe/WatchDogTimer.inf\r
   ${WORKSPACE}/MdeModulePkg/Universal/VariablePei/Variable.inf\r
-  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf
\ No newline at end of file
+  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf\r
+  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
\ No newline at end of file
index c9e2600..4fd7094 100644 (file)
   $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Pci/IdeBus/Dxe/IdeBus.inf\r
   $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf\r
   $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.inf\r
-  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf
\ No newline at end of file
+  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf     ##This driver follows UEFI specification definition\r
+  ${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf    ##This driver follows UEFI specification definition
\ No newline at end of file