summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Bus/Scsi
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Bus/Scsi')
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c155
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c751
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h266
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd44
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa68
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml47
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c190
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c2414
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h728
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd43
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa67
-rw-r--r--EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml47
12 files changed, 4820 insertions, 0 deletions
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c
new file mode 100644
index 0000000000..3f61c46d54
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ComponentName.c
@@ -0,0 +1,155 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "ScsiBus.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+ScsiBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+ScsiBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gScsiBusComponentName = {
+ ScsiBusComponentNameGetDriverName,
+ ScsiBusComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mScsiBusDriverNameTable[] = {
+ { "eng", (CHAR16 *) L"SCSI Bus Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+ScsiBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gScsiBusComponentName.SupportedLanguages,
+ mScsiBusDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+ScsiBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language
+ specified by Language from the point of view of the
+ driver specified by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c
new file mode 100644
index 0000000000..3aa31a812f
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c
@@ -0,0 +1,751 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ scsibus.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+#include "scsibus.h"
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {
+ SCSIBusDriverBindingSupported,
+ SCSIBusDriverBindingStart,
+ SCSIBusDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_UNSUPPORTED - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+
+ //
+ // If RemainingDevicePath is not NULL, it should verify that the first device
+ // path node in RemainingDevicePath is an ATAPI Device path node.
+ //
+ if (RemainingDevicePath != NULL) {
+ if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||
+ (RemainingDevicePath->SubType != MSG_ATAPI_DP) ||
+ (DevicePathNodeLength (RemainingDevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ //
+ // check for the existence of SCSI Pass Thru Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
+ UINT32 StartPun;
+ UINT64 StartLun;
+ UINT32 Pun;
+ UINT64 Lun;
+ BOOLEAN ScanOtherPuns;
+
+ StartPun = 0;
+ StartLun = 0;
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ //
+ // Consume SCSI Pass Thru protocol.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ (VOID **) &ScsiPassThru,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+
+ if (RemainingDevicePath == NULL) {
+ StartPun = 0xFFFFFFFF;
+ StartLun = 0;
+ } else {
+ ScsiPassThru->GetTargetLun (ScsiPassThru, RemainingDevicePath, &StartPun, &StartLun);
+ }
+
+ for (Pun = StartPun, ScanOtherPuns = TRUE; ScanOtherPuns;) {
+
+ if (StartPun == 0xFFFFFFFF) {
+ //
+ // Remaining Device Path is NULL, scan all the possible Puns in the
+ // SCSI Channel.
+ //
+ Status = ScsiPassThru->GetNextDevice (ScsiPassThru, &Pun, &Lun);
+ if (EFI_ERROR (Status)) {
+ //
+ // no legal Pun and Lun found any more
+ //
+ break;
+ }
+ } else {
+ //
+ // Remaining Device Path is not NULL, only scan the specified Pun.
+ //
+ Pun = StartPun;
+ Lun = StartLun;
+ ScanOtherPuns = FALSE;
+ }
+
+ //
+ // Avoid creating handle for the host adapter.
+ //
+ if (Pun == ScsiPassThru->Mode->AdapterId) {
+ continue;
+ }
+
+ //
+ // Scan for the scsi device, if it attaches to the scsi bus,
+ // then create handle and install scsi i/o protocol.
+ //
+ Status = ScsiScanCreateDevice (This, Controller, Pun, Lun, ScsiPassThru, ParentDevicePath);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SCSIBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: NumberOfChildren - add argument and description to function comment
+// TODO: ChildHandleBuffer - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ BOOLEAN AllChildrenStopped;
+ UINTN Index;
+ EFI_SCSI_IO_PROTOCOL *ScsiIo;
+ SCSI_IO_DEV *ScsiIoDevice;
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEfiScsiIoProtocolGuid,
+ (VOID **) &ScsiIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ continue;
+ }
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);
+ //
+ // Close the child handle
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ ScsiIoDevice->DevicePath,
+ &gEfiScsiIoProtocolGuid,
+ &ScsiIoDevice->ScsiIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ (VOID **) &ScsiPassThru,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ gBS->FreePool (ScsiIoDevice);
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiGetDeviceType (
+ IN EFI_SCSI_IO_PROTOCOL *This,
+ OUT UINT8 *DeviceType
+ )
+/*++
+
+ Routine Description:
+ Retrieves the device type information of the SCSI Controller.
+
+ Arguments:
+ This - Protocol instance pointer.
+ DeviceType - A pointer to the device type information
+ retrieved from the SCSI Controller.
+
+ Returns:
+ EFI_SUCCESS - Retrieves the device type information successfully.
+ EFI_INVALID_PARAMETER - The DeviceType is NULL.
+--*/
+{
+ SCSI_IO_DEV *ScsiIoDevice;
+
+ if (DeviceType == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
+ *DeviceType = ScsiIoDevice->ScsiDeviceType;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiGetDeviceLocation (
+ IN EFI_SCSI_IO_PROTOCOL *This,
+ OUT UINT8 **Target,
+ OUT UINT64 *Lun
+ )
+/*++
+ Routine Description:
+ Retrieves the device location in the SCSI channel.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Target - A pointer to the Target ID of a SCSI device
+ on the SCSI channel.
+ Lun - A pointer to the LUN of the SCSI device on
+ the SCSI channel.
+
+ Returns:
+ EFI_SUCCESS - Retrieves the device location successfully.
+ EFI_INVALID_PARAMETER - The Target or Lun is NULL.
+--*/
+{
+ SCSI_IO_DEV *ScsiIoDevice;
+
+ if (Target == NULL || Lun == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
+
+ *Target = (UINT8 *) (UINTN) ScsiIoDevice->Pun;
+ *Lun = ScsiIoDevice->Lun;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiResetBus (
+ IN EFI_SCSI_IO_PROTOCOL *This
+ )
+/*++
+
+ Routine Description:
+ Resets the SCSI Bus that the SCSI Controller is attached to.
+
+ Arguments:
+ This - Protocol instance pointer.
+
+ Returns:
+ EFI_SUCCESS - The SCSI bus is reset successfully.
+ EFI_DEVICE_ERROR - Errors encountered when resetting the SCSI bus.
+ EFI_UNSUPPORTED - The bus reset operation is not supported by the
+ SCSI Host Controller.
+ EFI_TIMEOUT - A timeout occurred while attempting to reset
+ the SCSI bus.
+--*/
+{
+ SCSI_IO_DEV *ScsiIoDevice;
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
+
+ return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);
+
+}
+
+EFI_STATUS
+EFIAPI
+ScsiResetDevice (
+ IN EFI_SCSI_IO_PROTOCOL *This
+ )
+/*++
+
+ Routine Description:
+ Resets the SCSI Controller that the device handle specifies.
+
+ Arguments:
+ This - Protocol instance pointer.
+
+
+ Returns:
+ EFI_SUCCESS - Reset the SCSI controller successfully.
+ EFI_DEVICE_ERROR - Errors are encountered when resetting the
+ SCSI Controller.
+ EFI_UNSUPPORTED - The SCSI bus does not support a device
+ reset operation.
+ EFI_TIMEOUT - A timeout occurred while attempting to
+ reset the SCSI Controller.
+--*/
+{
+ SCSI_IO_DEV *ScsiIoDevice;
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
+
+ return ScsiIoDevice->ScsiPassThru->ResetTarget (
+ ScsiIoDevice->ScsiPassThru,
+ ScsiIoDevice->Pun,
+ ScsiIoDevice->Lun
+ );
+}
+
+EFI_STATUS
+EFIAPI
+ScsiExecuteSCSICommand (
+ IN EFI_SCSI_IO_PROTOCOL *This,
+ IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,
+ IN EFI_EVENT Event OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Sends a SCSI Request Packet to the SCSI Controller for execution.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Packet - The SCSI request packet to send to the SCSI
+ Controller specified by the device handle.
+ Event - If the SCSI bus where the SCSI device is attached
+ does not support non-blocking I/O, then Event is
+ ignored, and blocking I/O is performed.
+ If Event is NULL, then blocking I/O is performed.
+ If Event is not NULL and non-blocking I/O is
+ supported, then non-blocking I/O is performed,
+ and Event will be signaled when the SCSI Request
+ Packet completes.
+ Returns:
+ EFI_SUCCESS - The SCSI Request Packet was sent by the host
+ successfully, and TransferLength bytes were
+ transferred to/from DataBuffer.See
+ HostAdapterStatus, TargetStatus,
+ SenseDataLength, and SenseData in that order
+ for additional status information.
+ EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
+ but the entire DataBuffer could not be transferred.
+ The actual number of bytes transferred is returned
+ in TransferLength. See HostAdapterStatus,
+ TargetStatus, SenseDataLength, and SenseData in
+ that order for additional status information.
+ EFI_NOT_READY - The SCSI Request Packet could not be sent because
+ there are too many SCSI Command Packets already
+ queued.The caller may retry again later.
+ EFI_DEVICE_ERROR - A device error occurred while attempting to send
+ the SCSI Request Packet. See HostAdapterStatus,
+ TargetStatus, SenseDataLength, and SenseData in
+ that order for additional status information.
+ EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
+ The SCSI Request Packet was not sent, so no
+ additional status information is available.
+ EFI_UNSUPPORTED - The command described by the SCSI Request Packet
+ is not supported by the SCSI initiator(i.e., SCSI
+ Host Controller). The SCSI Request Packet was not
+ sent, so no additional status information is
+ available.
+ EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
+ Request Packet to execute. See HostAdapterStatus,
+ TargetStatus, SenseDataLength, and SenseData in
+ that order for additional status information.
+--*/
+{
+ SCSI_IO_DEV *ScsiIoDevice;
+ EFI_STATUS Status;
+
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *RequestPacket;
+
+ if (Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
+
+ RequestPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;
+
+ Status = ScsiIoDevice->ScsiPassThru->PassThru (
+ ScsiIoDevice->ScsiPassThru,
+ ScsiIoDevice->Pun,
+ ScsiIoDevice->Lun,
+ RequestPacket,
+ Event
+ );
+ return Status;
+}
+
+EFI_STATUS
+ScsiScanCreateDevice (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINT32 Pun,
+ UINT64 Lun,
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Controller - TODO: add argument description
+ Pun - TODO: add argument description
+ Lun - TODO: add argument description
+ ScsiPassThru - TODO: add argument description
+ ParentDevicePath - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_OUT_OF_RESOURCES - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ SCSI_IO_DEV *ScsiIoDevice;
+ EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SCSI_IO_DEV),
+ (VOID **) &ScsiIoDevice
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ZeroMem (ScsiIoDevice, sizeof (SCSI_IO_DEV));
+
+ ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;
+ ScsiIoDevice->ScsiPassThru = ScsiPassThru;
+ ScsiIoDevice->Pun = Pun;
+ ScsiIoDevice->Lun = Lun;
+
+ ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;
+ ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;
+ ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;
+ ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;
+ ScsiIoDevice->ScsiIo.ExecuteSCSICommand = ScsiExecuteSCSICommand;
+
+ if (!DiscoverScsiDevice (ScsiIoDevice)) {
+ gBS->FreePool (ScsiIoDevice);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Set Device Path
+ //
+ Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (
+ ScsiIoDevice->ScsiPassThru,
+ ScsiIoDevice->Pun,
+ ScsiIoDevice->Lun,
+ &ScsiDevicePath
+ );
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ gBS->FreePool (ScsiIoDevice);
+ return Status;
+ }
+
+ ScsiIoDevice->DevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ ScsiDevicePath
+ );
+ //
+ // The memory space for ScsiDevicePath is allocated in
+ // ScsiPassThru->BuildDevicePath() function; It is no longer used
+ // after EfiAppendDevicePathNode,so free the memory it occupies.
+ //
+ gBS->FreePool (ScsiDevicePath);
+
+ if (ScsiIoDevice->DevicePath == NULL) {
+ gBS->FreePool (ScsiIoDevice);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ScsiIoDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ ScsiIoDevice->DevicePath,
+ &gEfiScsiIoProtocolGuid,
+ &ScsiIoDevice->ScsiIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (ScsiIoDevice);
+ } else {
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiPassThruProtocolGuid,
+ (VOID **) &ScsiPassThru,
+ This->DriverBindingHandle,
+ ScsiIoDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+DiscoverScsiDevice (
+ SCSI_IO_DEV *ScsiIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SCSI_INQUIRY_DATA InquiryData;
+ UINT32 InquiryDataLength;
+ EFI_SCSI_SENSE_DATA SenseData;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ HostAdapterStatus = 0;
+ TargetStatus = 0;
+ //
+ // Using Inquiry command to scan for the device
+ //
+ InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
+ SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);
+
+ Status = SubmitInquiryCommand (
+ &ScsiIoDevice->ScsiIo,
+ EfiScsiStallSeconds (1),
+ (VOID *) &SenseData,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &InquiryData,
+ &InquiryDataLength,
+ FALSE
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // ParseSenseData (&SenseData,SenseDataLength);
+ //
+ return FALSE;
+ }
+ //
+ // Retrieved inquiry data successfully
+ //
+ if ((InquiryData.Peripheral_Qualifier != 0) &&
+ (InquiryData.Peripheral_Qualifier != 3)) {
+ return FALSE;
+ }
+
+ if (InquiryData.Peripheral_Qualifier == 3) {
+ if (InquiryData.Peripheral_Type != 0x1f) {
+ return FALSE;
+ }
+ }
+
+ if ((0x1e >= InquiryData.Peripheral_Type) && (InquiryData.Peripheral_Type >= 0xa)) {
+ return FALSE;
+ }
+
+ //
+ // valid device type and peripheral qualifier combination.
+ //
+ ScsiIoDevice->ScsiDeviceType = InquiryData.Peripheral_Type;
+ ScsiIoDevice->RemovableDevice = InquiryData.RMB;
+ if (InquiryData.Version == 0) {
+ ScsiIoDevice->ScsiVersion = 0;
+ } else {
+ //
+ // ANSI-approved version
+ //
+ ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);
+ }
+
+ return TRUE;
+}
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h
new file mode 100644
index 0000000000..da1fa23bfa
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.h
@@ -0,0 +1,266 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ scsibus.h
+
+Abstract:
+
+ Header file for SCSI Bus Driver.
+
+Revision History
+++*/
+
+// TODO: fix comment to end with --*/
+#ifndef _SCSI_BUS_H
+#define _SCSI_BUS_H
+
+
+#include <IndustryStandard/scsi.h>
+//
+// 1000 * 1000 * 10
+//
+#define ONE_SECOND_TIMER 10000000
+
+#define SCSI_IO_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'c', 'i', 'o')
+
+typedef struct {
+ UINT32 Signature;
+
+ EFI_HANDLE Handle;
+ EFI_SCSI_IO_PROTOCOL ScsiIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
+
+ UINT32 Pun;
+ UINT64 Lun;
+ UINT8 ScsiDeviceType;
+ UINT8 ScsiVersion;
+ BOOLEAN RemovableDevice;
+} SCSI_IO_DEV;
+
+#define SCSI_IO_DEV_FROM_THIS(a) CR (a, SCSI_IO_DEV, ScsiIo, SCSI_IO_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gScsiBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gScsiBusComponentName;
+
+EFI_STATUS
+EFIAPI
+ScsiGetDeviceType (
+ IN EFI_SCSI_IO_PROTOCOL *This,
+ OUT UINT8 *DeviceType
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ DeviceType - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiResetBus (
+ IN EFI_SCSI_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiResetDevice (
+ IN EFI_SCSI_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiExecuteSCSICommand (
+ IN EFI_SCSI_IO_PROTOCOL *This,
+ IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *CommandPacket,
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ CommandPacket - TODO: add argument description
+ Event - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiScanCreateDevice (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINT32 Pun,
+ UINT64 Lun,
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Controller - TODO: add argument description
+ Pun - TODO: add argument description
+ Lun - TODO: add argument description
+ ScsiPassThru - TODO: add argument description
+ ParentDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+DiscoverScsiDevice (
+ SCSI_IO_DEV *ScsiIoDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiIoDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+GetLunList (
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,
+ UINT32 Target,
+ UINT64 **LunArray,
+ UINTN *NumberOfLuns
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiPassThru - TODO: add argument description
+ Target - TODO: add argument description
+ LunArray - TODO: add argument description
+ NumberOfLuns - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiBusSubmitReportLunCommand (
+ EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,
+ UINT32 Target,
+ UINTN AllocationLength,
+ VOID *Buffer,
+ EFI_SCSI_SENSE_DATA *SenseData,
+ UINT8 *SenseDataLength,
+ UINT8 *HostAdapterStatus,
+ UINT8 *TargetStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiPassThru - TODO: add argument description
+ Target - TODO: add argument description
+ AllocationLength - TODO: add argument description
+ Buffer - TODO: add argument description
+ SenseData - TODO: add argument description
+ SenseDataLength - TODO: add argument description
+ HostAdapterStatus - TODO: add argument description
+ TargetStatus - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+#endif
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd
new file mode 100644
index 0000000000..0254903cd1
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.mbd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>ScsiBus</BaseName>
+ <Guid>0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:18</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>UefiDriverModelLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>EdkDxePrintLib</Library>
+ <Library>BaseLib</Library>
+ <Library>EdkScsiLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ <Library>UefiDevicePathLib</Library>
+ </Libraries>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa
new file mode 100644
index 0000000000..c4c0b4566b
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>ScsiBus</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for Scsi Bus module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:18</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkScsiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DevicePathLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>ScsiBus.h</Filename>
+ <Filename>ScsiBus.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="TO_START">ScsiPassThru</Protocol>
+ <Protocol Usage="TO_START">DevicePath</Protocol>
+ <Protocol Usage="BY_START">ScsiIo</Protocol>
+ </Protocols>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint></ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <DriverBinding>gSCSIBusDriverBinding</DriverBinding>
+ <ComponentName>gScsiBusComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml
new file mode 100644
index 0000000000..9942471bb9
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<project basedir="." default="ScsiBus"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Bus\Scsi\ScsiBus\Dxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="ScsiBus">
+ <GenBuild baseName="ScsiBus" mbdFilename="${MODULE_DIR}\ScsiBus.mbd" msaFilename="${MODULE_DIR}\ScsiBus.msa"/>
+ </target>
+ <target depends="ScsiBus_clean" name="clean"/>
+ <target depends="ScsiBus_cleanall" name="cleanall"/>
+ <target name="ScsiBus_clean">
+ <OutputDirSetup baseName="ScsiBus" mbdFilename="${MODULE_DIR}\ScsiBus.mbd" msaFilename="${MODULE_DIR}\ScsiBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\ScsiBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\ScsiBus_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="ScsiBus_cleanall">
+ <OutputDirSetup baseName="ScsiBus" mbdFilename="${MODULE_DIR}\ScsiBus.mbd" msaFilename="${MODULE_DIR}\ScsiBus.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\ScsiBus_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\ScsiBus_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**ScsiBus*"/>
+ </delete>
+ </target>
+</project> \ No newline at end of file
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c
new file mode 100644
index 0000000000..15f02d6c41
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ComponentName.c
@@ -0,0 +1,190 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "ScsiDisk.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+ScsiDiskComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+ScsiDiskComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gScsiDiskComponentName = {
+ ScsiDiskComponentNameGetDriverName,
+ ScsiDiskComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mScsiDiskDriverNameTable[] = {
+ { "eng", (CHAR16 *) L"Scsi Disk Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+ScsiDiskComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gScsiDiskComponentName.SupportedLanguages,
+ mScsiDiskDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language
+ specified by Language from the point of view of the
+ driver specified by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlockIo,
+ gScsiDiskDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlockIo);
+
+ return LookupUnicodeString (
+ Language,
+ gScsiDiskComponentName.SupportedLanguages,
+ ScsiDiskDevice->ControllerNameTable,
+ ControllerName
+ );
+
+}
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
new file mode 100644
index 0000000000..2c6fd29d37
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.c
@@ -0,0 +1,2414 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ScsiDisk.c
+
+Abstract:
+
+--*/
+
+#include "scsidisk.h"
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding = {
+ ScsiDiskDriverBindingSupported,
+ ScsiDiskDriverBindingStart,
+ ScsiDiskDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_SCSI_IO_PROTOCOL *ScsiIo;
+ UINT8 DeviceType;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ (VOID **) &ScsiIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = ScsiIo->GetDeviceType (ScsiIo, &DeviceType);
+ if (!EFI_ERROR (Status)) {
+ if ((DeviceType == EFI_SCSI_TYPE_DISK) || (DeviceType == EFI_SCSI_TYPE_CDROM)) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: RemainingDevicePath - add argument and description to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_SCSI_IO_PROTOCOL *ScsiIo;
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ BOOLEAN Temp;
+ UINT8 Index;
+ UINT8 MaxRetry;
+ BOOLEAN NeedRetry;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (SCSI_DISK_DEV),
+ (VOID **) &ScsiDiskDevice
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ZeroMem (ScsiDiskDevice, sizeof (SCSI_DISK_DEV));
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ (VOID **) &ScsiIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (ScsiDiskDevice);
+ return Status;
+ }
+
+ ScsiDiskDevice->Signature = SCSI_DISK_DEV_SIGNATURE;
+ ScsiDiskDevice->ScsiIo = ScsiIo;
+ ScsiDiskDevice->BlkIo.Media = &ScsiDiskDevice->BlkIoMedia;
+ ScsiDiskDevice->BlkIo.Reset = ScsiDiskReset;
+ ScsiDiskDevice->BlkIo.ReadBlocks = ScsiDiskReadBlocks;
+ ScsiDiskDevice->BlkIo.WriteBlocks = ScsiDiskWriteBlocks;
+ ScsiDiskDevice->BlkIo.FlushBlocks = ScsiDiskFlushBlocks;
+ ScsiDiskDevice->Handle = Controller;
+
+ ScsiIo->GetDeviceType (ScsiIo, &(ScsiDiskDevice->DeviceType));
+ switch (ScsiDiskDevice->DeviceType) {
+ case EFI_SCSI_TYPE_DISK:
+ ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;
+ break;
+
+ case EFI_SCSI_TYPE_CDROM:
+ ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;
+ break;
+ }
+ //
+ // The Sense Data Array's initial size is 6
+ //
+ ScsiDiskDevice->SenseDataNumber = 6;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber,
+ (VOID **) &(ScsiDiskDevice->SenseData)
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->FreePool (ScsiDiskDevice);
+ return Status;
+ }
+
+ ZeroMem (
+ ScsiDiskDevice->SenseData,
+ sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber
+ );
+
+ //
+ // Retrive device information
+ //
+ MaxRetry = 2;
+ for (Index = 0; Index < MaxRetry; Index++) {
+ Status = ScsiDiskInquiryDevice (ScsiDiskDevice, &NeedRetry);
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (!NeedRetry) {
+ gBS->FreePool (ScsiDiskDevice->SenseData);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->FreePool (ScsiDiskDevice);
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //
+ // The second parameter "TRUE" means must
+ // retrieve media capacity
+ //
+ Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiBlockIoProtocolGuid,
+ &ScsiDiskDevice->BlkIo,
+ NULL
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (ScsiDiskDevice->SenseData);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->FreePool (ScsiDiskDevice);
+ return Status;
+ }
+
+ ScsiDiskDevice->ControllerNameTable = NULL;
+ AddUnicodeString (
+ "eng",
+ gScsiDiskComponentName.SupportedLanguages,
+ &ScsiDiskDevice->ControllerNameTable,
+ (CHAR16 *) L"SCSI Disk Device"
+ );
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Arguments:
+
+ Returns:
+
+--*/
+// TODO: This - add argument and description to function comment
+// TODO: Controller - add argument and description to function comment
+// TODO: NumberOfChildren - add argument and description to function comment
+// TODO: ChildHandleBuffer - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlkIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (BlkIo);
+ Status = gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiBlockIoProtocolGuid,
+ &ScsiDiskDevice->BlkIo
+ );
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiScsiIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ ReleaseScsiDiskDeviceResources (ScsiDiskDevice);
+
+ return EFI_SUCCESS;
+ }
+ //
+ // errors met
+ //
+ return Status;
+}
+
+//
+// Block I/O Protocol Interface
+//
+
+EFI_STATUS
+EFIAPI
+ScsiDiskReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ EFI_STATUS Status;
+
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
+
+ Status = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
+
+ if (!ExtendedVerification) {
+ return Status;
+ }
+
+ Status = ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ LBA - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_NO_MEDIA - TODO: Add description for return value
+ EFI_MEDIA_CHANGED - TODO: Add description for return value
+ EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+
+--*/
+{
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_STATUS Status;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ BOOLEAN MediaChange;
+
+ MediaChange = FALSE;
+ if (!Buffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
+
+ if (!IsDeviceFixed (ScsiDiskDevice)) {
+
+ Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (MediaChange) {
+ gBS->ReinstallProtocolInterface (
+ ScsiDiskDevice->Handle,
+ &gEfiBlockIoProtocolGuid,
+ &ScsiDiskDevice->BlkIo,
+ &ScsiDiskDevice->BlkIo
+ );
+ }
+ }
+ //
+ // Get the intrinsic block size
+ //
+ Media = ScsiDiskDevice->BlkIo.Media;
+ BlockSize = Media->BlockSize;
+
+ NumberOfBlocks = BufferSize / BlockSize;
+
+ if (!(Media->MediaPresent)) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (BufferSize % BlockSize != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (LBA > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // if all the parameters are valid, then perform read sectors command
+ // to transfer data from device to host.
+ //
+ Status = ScsiDiskReadSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ LBA - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_NO_MEDIA - TODO: Add description for return value
+ EFI_MEDIA_CHANGED - TODO: Add description for return value
+ EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+ EFI_INVALID_PARAMETER - TODO: Add description for return value
+
+--*/
+{
+ SCSI_DISK_DEV *ScsiDiskDevice;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_STATUS Status;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ BOOLEAN MediaChange;
+
+ MediaChange = FALSE;
+ if (!Buffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ ScsiDiskDevice = SCSI_DISK_DEV_FROM_THIS (This);
+
+ if (!IsDeviceFixed (ScsiDiskDevice)) {
+
+ Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (MediaChange) {
+ gBS->ReinstallProtocolInterface (
+ ScsiDiskDevice->Handle,
+ &gEfiBlockIoProtocolGuid,
+ &ScsiDiskDevice->BlkIo,
+ &ScsiDiskDevice->BlkIo
+ );
+ }
+ }
+ //
+ // Get the intrinsic block size
+ //
+ Media = ScsiDiskDevice->BlkIo.Media;
+ BlockSize = Media->BlockSize;
+
+ NumberOfBlocks = BufferSize / BlockSize;
+
+ if (!(Media->MediaPresent)) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (BufferSize % BlockSize != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (LBA > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // if all the parameters are valid, then perform read sectors command
+ // to transfer data from device to host.
+ //
+ Status = ScsiDiskWriteSectors (ScsiDiskDevice, Buffer, LBA, NumberOfBlocks);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ScsiDiskFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ //
+ // return directly
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScsiDiskDetectMedia (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN MustReadCapacity,
+ BOOLEAN *MediaChange
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ MustReadCapacity - TODO: add argument description
+ MediaChange - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReadCapacityStatus;
+ EFI_SCSI_SENSE_DATA *SenseData;
+ UINTN NumberOfSenseKeys;
+ BOOLEAN NeedRetry;
+ BOOLEAN NeedReadCapacity;
+ UINT8 Index;
+ UINT8 MaxRetry;
+ EFI_BLOCK_IO_MEDIA OldMedia;
+ UINTN Action;
+
+ Status = EFI_SUCCESS;
+ ReadCapacityStatus = EFI_SUCCESS;
+ SenseData = NULL;
+ NumberOfSenseKeys = 0;
+ NeedReadCapacity = FALSE;
+ CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));
+ // OldMedia = *(ScsiDiskDevice->BlkIo.Media);
+
+ *MediaChange = FALSE;
+
+ MaxRetry = 3;
+ for (Index = 0; Index < MaxRetry; Index++) {
+ Status = ScsiDiskTestUnitReady (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (!NeedRetry) {
+ return Status;
+ }
+ }
+
+ if ((Index == MaxRetry) && EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = DetectMediaParsingSenseKeys (
+ ScsiDiskDevice,
+ SenseData,
+ NumberOfSenseKeys,
+ &Action
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // ACTION_NO_ACTION: need not read capacity
+ // other action code: need read capacity
+ //
+ if (Action == ACTION_NO_ACTION) {
+ NeedReadCapacity = FALSE;
+ } else {
+ NeedReadCapacity = TRUE;
+ }
+
+ //
+ // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,
+ // retrieve capacity via Read Capacity command
+ //
+ if (NeedReadCapacity || MustReadCapacity) {
+
+ //
+ // retrieve media information
+ //
+ MaxRetry = 3;
+ for (Index = 0; Index < MaxRetry; Index++) {
+
+ ReadCapacityStatus = ScsiDiskReadCapacity (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys
+ );
+ if (EFI_ERROR (ReadCapacityStatus) && !NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // analyze sense key to action
+ //
+ Status = DetectMediaParsingSenseKeys (
+ ScsiDiskDevice,
+ SenseData,
+ NumberOfSenseKeys,
+ &Action
+ );
+ //
+ // if Status is error, it may indicate crisis error,
+ // so return without retry.
+ //
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ switch (Action) {
+ case ACTION_NO_ACTION:
+ //
+ // no retry
+ //
+ Index = MaxRetry;
+ break;
+
+ case ACTION_RETRY_COMMAND_LATER:
+ //
+ // retry the ReadCapacity later and continuously, until the condition
+ // no longer emerges.
+ // stall time is 100000us, or say 0.1 second.
+ //
+ gBS->Stall (100000);
+ Index = 0;
+ break;
+
+ default:
+ //
+ // other cases, just retry the command
+ //
+ break;
+ }
+ }
+
+ if ((Index == MaxRetry) && EFI_ERROR (ReadCapacityStatus)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if (ScsiDiskDevice->BlkIo.Media->MediaId != OldMedia.MediaId) {
+ //
+ // Media change information got from the device
+ //
+ *MediaChange = TRUE;
+ }
+
+ if (ScsiDiskDevice->BlkIo.Media->ReadOnly != OldMedia.ReadOnly) {
+ *MediaChange = TRUE;
+ ScsiDiskDevice->BlkIo.Media->MediaId += 1;
+ }
+
+ if (ScsiDiskDevice->BlkIo.Media->BlockSize != OldMedia.BlockSize) {
+ *MediaChange = TRUE;
+ ScsiDiskDevice->BlkIo.Media->MediaId += 1;
+ }
+
+ if (ScsiDiskDevice->BlkIo.Media->LastBlock != OldMedia.LastBlock) {
+ *MediaChange = TRUE;
+ ScsiDiskDevice->BlkIo.Media->MediaId += 1;
+ }
+
+ if (ScsiDiskDevice->BlkIo.Media->MediaPresent != OldMedia.MediaPresent) {
+ if (ScsiDiskDevice->BlkIo.Media->MediaPresent) {
+ //
+ // when change from no media to media present, reset the MediaId to 1.
+ //
+ ScsiDiskDevice->BlkIo.Media->MediaId = 1;
+ } else {
+ //
+ // when no media, reset the MediaId to zero.
+ //
+ ScsiDiskDevice->BlkIo.Media->MediaId = 0;
+ }
+
+ *MediaChange = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScsiDiskInquiryDevice (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+
+--*/
+{
+ UINT32 InquiryDataLength;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+ EFI_SCSI_SENSE_DATA *SenseDataArray;
+ UINTN NumberOfSenseKeys;
+ EFI_STATUS Status;
+ UINT8 MaxRetry;
+ UINT8 Index;
+
+ InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
+ SenseDataLength = 0;
+
+ Status = SubmitInquiryCommand (
+ ScsiDiskDevice->ScsiIo,
+ EfiScsiStallSeconds (1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &(ScsiDiskDevice->InquiryData),
+ &InquiryDataLength,
+ FALSE
+ );
+ switch (Status) {
+ //
+ // no need to check HostAdapterStatus and TargetStatus
+ //
+ case EFI_SUCCESS:
+ case EFI_WARN_BUFFER_TOO_SMALL:
+ ParseInquiryData (ScsiDiskDevice);
+ return EFI_SUCCESS;
+
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+
+ //
+ // go ahead to check HostAdapterStatus and TargetStatus
+ // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
+ //
+ default:
+ break;
+ }
+
+ Status = CheckHostAdapterStatus (HostAdapterStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_TIMEOUT:
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ //
+ // reset the scsi channel
+ //
+ ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = CheckTargetStatus (TargetStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_NOT_READY:
+ //
+ // reset the scsi device
+ //
+ ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // if goes here, meant SubmitInquiryCommand() failed.
+ // if ScsiDiskRequestSenseKeys() succeeds at last,
+ // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)
+ //
+ MaxRetry = 3;
+ for (Index = 0; Index < MaxRetry; Index++) {
+
+ Status = ScsiDiskRequestSenseKeys (
+ ScsiDiskDevice,
+ NeedRetry,
+ &SenseDataArray,
+ &NumberOfSenseKeys,
+ TRUE
+ );
+ if (!EFI_ERROR (Status)) {
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (!*NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //
+ // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
+ // set *NeedRetry = FALSE to avoid the outside caller try again.
+ //
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+ScsiDiskTestUnitReady (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys
+ )
+// TODO: function comment should start with '/*++'
+/*
+ When Test Unit Ready command succeeds,
+ retrieve Sense Keys via Request Sense;
+ When Test Unit Ready command encounters any error caused by host adapter or
+ target, return error without retrieving Sense Keys.
+*/
+// TODO: function comment should end with '--*/'
+// TODO: function comment is missing 'Routine Description:'
+// TODO: function comment is missing 'Arguments:'
+// TODO: function comment is missing 'Returns:'
+// TODO: ScsiDiskDevice - add argument and description to function comment
+// TODO: NeedRetry - add argument and description to function comment
+// TODO: SenseDataArray - add argument and description to function comment
+// TODO: NumberOfSenseKeys - add argument and description to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+{
+ EFI_STATUS Status;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+ UINT8 Index;
+ UINT8 MaxRetry;
+
+ SenseDataLength = 0;
+ *NumberOfSenseKeys = 0;
+
+ //
+ // Parameter 3 and 4: do not require sense data, retrieve it when needed.
+ //
+ Status = SubmitTestUnitReadyCommand (
+ ScsiDiskDevice->ScsiIo,
+ EfiScsiStallSeconds (1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus
+ );
+ switch (Status) {
+ //
+ // no need to check HostAdapterStatus and TargetStatus
+ //
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+
+ //
+ // go ahead to check HostAdapterStatus and TargetStatus
+ //
+ default:
+ break;
+ }
+
+ Status = CheckHostAdapterStatus (HostAdapterStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_TIMEOUT:
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ //
+ // reset the scsi channel
+ //
+ ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = CheckTargetStatus (TargetStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_NOT_READY:
+ //
+ // reset the scsi device
+ //
+ ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ MaxRetry = 3;
+ for (Index = 0; Index < MaxRetry; Index++) {
+
+ Status = ScsiDiskRequestSenseKeys (
+ ScsiDiskDevice,
+ NeedRetry,
+ SenseDataArray,
+ NumberOfSenseKeys,
+ FALSE
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ if (!*NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //
+ // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
+ // set *NeedRetry = FALSE to avoid the outside caller try again.
+ //
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+DetectMediaParsingSenseKeys (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ EFI_SCSI_SENSE_DATA *SenseData,
+ UINTN NumberOfSenseKeys,
+ UINTN *Action
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ SenseData - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Action - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ BOOLEAN RetryLater;
+
+ //
+ // Default is to read capacity, unless..
+ //
+ *Action = ACTION_READ_CAPACITY;
+
+ if (NumberOfSenseKeys == 0) {
+ *Action = ACTION_NO_ACTION;
+ return EFI_SUCCESS;
+ }
+
+ if (!ScsiDiskHaveSenseKey (SenseData, NumberOfSenseKeys)) {
+ //
+ // No Sense Key returned from last submitted command
+ //
+ *Action = ACTION_NO_ACTION;
+ return EFI_SUCCESS;
+ }
+
+ if (ScsiDiskIsNoMedia (SenseData, NumberOfSenseKeys)) {
+ ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
+ ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
+ *Action = ACTION_NO_ACTION;
+ return EFI_SUCCESS;
+ }
+
+ if (ScsiDiskIsMediaChange (SenseData, NumberOfSenseKeys)) {
+ ScsiDiskDevice->BlkIo.Media->MediaId++;
+ return EFI_SUCCESS;
+ }
+
+ if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {
+ ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;
+ ScsiDiskDevice->BlkIo.Media->LastBlock = 0;
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (!ScsiDiskIsDriveReady (SenseData, NumberOfSenseKeys, &RetryLater)) {
+ if (RetryLater) {
+ *Action = ACTION_RETRY_COMMAND_LATER;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScsiDiskReadCapacity (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+
+--*/
+{
+ EFI_SCSI_DISK_CAPACITY_DATA CapacityData;
+ UINT32 DataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+ EFI_STATUS CommandStatus;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT8 MaxRetry;
+ UINT8 SenseDataLength;
+
+ SenseDataLength = 0;
+ ZeroMem (&CapacityData, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));
+ DataLength = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);
+
+ *NumberOfSenseKeys = 0;
+ *NeedRetry = FALSE;
+ //
+ // submit Read Capacity Command. in this call,not request sense data
+ //
+ CommandStatus = SubmitReadCapacityCommand (
+ ScsiDiskDevice->ScsiIo,
+ EfiScsiStallSeconds (1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &CapacityData,
+ &DataLength,
+ FALSE
+ );
+ switch (CommandStatus) {
+ //
+ // no need to check HostAdapterStatus and TargetStatus
+ //
+ case EFI_SUCCESS:
+ GetMediaInfo (ScsiDiskDevice, &CapacityData);
+ return EFI_SUCCESS;
+
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+
+ //
+ // go ahead to check HostAdapterStatus and TargetStatus
+ // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)
+ //
+ default:
+ break;
+ }
+
+ Status = CheckHostAdapterStatus (HostAdapterStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_TIMEOUT:
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ //
+ // reset the scsi channel
+ //
+ ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = CheckTargetStatus (TargetStatus);
+ switch (Status) {
+ case EFI_SUCCESS:
+ break;
+
+ case EFI_NOT_READY:
+ //
+ // reset the scsi device
+ //
+ ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+
+ case EFI_DEVICE_ERROR:
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // if goes here, meant SubmitReadCapacityCommand() failed.
+ // if ScsiDiskRequestSenseKeys() succeeds at last,
+ // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)
+ //
+ MaxRetry = 3;
+ for (Index = 0; Index < MaxRetry; Index++) {
+
+ Status = ScsiDiskRequestSenseKeys (
+ ScsiDiskDevice,
+ NeedRetry,
+ SenseDataArray,
+ NumberOfSenseKeys,
+ TRUE
+ );
+ if (!EFI_ERROR (Status)) {
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (!*NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //
+ // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
+ // set *NeedRetry = FALSE to avoid the outside caller try again.
+ //
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+CheckHostAdapterStatus (
+ UINT8 HostAdapterStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HostAdapterStatus - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_TIMEOUT - TODO: Add description for return value
+ EFI_NOT_READY - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ switch (HostAdapterStatus) {
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK:
+ return EFI_SUCCESS;
+
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND:
+ return EFI_TIMEOUT;
+
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET:
+ return EFI_NOT_READY;
+
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE:
+ case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR:
+ return EFI_DEVICE_ERROR;
+
+ default:
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+CheckTargetStatus (
+ UINT8 TargetStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ TargetStatus - TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - TODO: Add description for return value
+ EFI_NOT_READY - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ switch (TargetStatus) {
+ case EFI_SCSI_IO_STATUS_TARGET_GOOD:
+ case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION:
+ case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET:
+ return EFI_SUCCESS;
+
+ case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE:
+ case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET:
+ case EFI_SCSI_IO_STATUS_TARGET_BUSY:
+ case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED:
+ case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL:
+ return EFI_NOT_READY;
+
+ case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT:
+ return EFI_DEVICE_ERROR;
+ break;
+
+ default:
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+ScsiDiskRequestSenseKeys (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ BOOLEAN AskResetIfError
+ )
+// TODO: function comment should start with '/*++'
+/*
+ Retrieve all sense keys from the device.
+ When encountering error during the process,
+ if retrieve sense keys before error encounterred,
+ return the sense keys with return status set to EFI_SUCCESS,
+ and NeedRetry set to FALSE; otherwize, return the proper return
+ status.
+*/
+// TODO: function comment should end with '--*/'
+// TODO: function comment is missing 'Routine Description:'
+// TODO: function comment is missing 'Arguments:'
+// TODO: function comment is missing 'Returns:'
+// TODO: ScsiDiskDevice - add argument and description to function comment
+// TODO: NeedRetry - add argument and description to function comment
+// TODO: SenseDataArray - add argument and description to function comment
+// TODO: NumberOfSenseKeys - add argument and description to function comment
+// TODO: AskResetIfError - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_DEVICE_ERROR - add return value to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_SCSI_SENSE_DATA *PtrSenseData;
+ UINT8 SenseDataLength;
+ BOOLEAN SenseReq;
+ EFI_STATUS Status;
+ EFI_STATUS FallStatus;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ FallStatus = EFI_SUCCESS;
+ SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);
+
+ ZeroMem (
+ ScsiDiskDevice->SenseData,
+ sizeof (EFI_SCSI_SENSE_DATA) * (ScsiDiskDevice->SenseDataNumber)
+ );
+
+ *NumberOfSenseKeys = 0;
+ *SenseDataArray = ScsiDiskDevice->SenseData;
+ PtrSenseData = ScsiDiskDevice->SenseData;
+
+ for (SenseReq = TRUE; SenseReq;) {
+
+ Status = SubmitRequestSenseCommand (
+ ScsiDiskDevice->ScsiIo,
+ EfiScsiStallSeconds (2),
+ PtrSenseData,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus
+ );
+ switch (Status) {
+
+ case EFI_SUCCESS:
+
+ //
+ // fall through
+ //
+ case EFI_WARN_BUFFER_TOO_SMALL:
+ FallStatus = EFI_SUCCESS;
+ break;
+
+ case EFI_TIMEOUT:
+
+ //
+ // fall through
+ //
+ case EFI_NOT_READY:
+ *NeedRetry = TRUE;
+ FallStatus = EFI_DEVICE_ERROR;
+ break;
+
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ *NeedRetry = FALSE;
+ FallStatus = EFI_DEVICE_ERROR;
+ break;
+
+ case EFI_DEVICE_ERROR:
+ if (AskResetIfError) {
+ ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);
+ }
+
+ FallStatus = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ if (EFI_ERROR (FallStatus)) {
+ if (*NumberOfSenseKeys != 0) {
+ *NeedRetry = FALSE;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ (*NumberOfSenseKeys) += 1;
+
+ //
+ // no more sense key or number of sense keys exceeds predefined,
+ // skip the loop.
+ //
+ if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
+ (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber)) {
+ SenseReq = FALSE;
+ }
+
+ PtrSenseData += 1;
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+GetMediaInfo (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ EFI_SCSI_DISK_CAPACITY_DATA *Capacity
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Capacity - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity->LastLba3 << 24) |
+ (Capacity->LastLba2 << 16) |
+ (Capacity->LastLba1 << 8) |
+ Capacity->LastLba0;
+
+ ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;
+ ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity->BlockSize3 << 24) |
+ (Capacity->BlockSize2 << 16) |
+ (Capacity->BlockSize1 << 8) |
+ Capacity->BlockSize0;
+ if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {
+ ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;
+ }
+
+ if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_CDROM) {
+ ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;
+ }
+}
+
+VOID
+ParseInquiryData (
+ SCSI_DISK_DEV *ScsiDiskDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ ScsiDiskDevice->FixedDevice = (BOOLEAN) (ScsiDiskDevice->InquiryData.RMB ? 0 : 1);
+ ScsiDiskDevice->BlkIoMedia.RemovableMedia = (BOOLEAN) (!ScsiDiskDevice->FixedDevice);
+}
+
+EFI_STATUS
+ScsiDiskReadSectors (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ VOID *Buffer,
+ EFI_LBA Lba,
+ UINTN NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Buffer - TODO: add argument description
+ Lba - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UINTN BlocksRemaining;
+ UINT32 Lba32;
+ UINT8 *PtrBuffer;
+ UINT32 BlockSize;
+ UINT32 ByteCount;
+ UINT32 MaxBlock;
+ UINT32 SectorCount;
+ UINT64 Timeout;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT8 MaxRetry;
+ BOOLEAN NeedRetry;
+ EFI_SCSI_SENSE_DATA *SenseData;
+ UINT8 SenseDataLength;
+ UINTN NumberOfSenseKeys;
+
+ SenseData = NULL;
+ SenseDataLength = 0;
+ NumberOfSenseKeys = 0;
+
+ Status = EFI_SUCCESS;
+
+ BlocksRemaining = NumberOfBlocks;
+ BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
+ //
+ // limit the data bytes that can be transferred by one Read(10) Command
+ //
+ MaxBlock = 65536;
+
+ PtrBuffer = Buffer;
+ Lba32 = (UINT32) Lba;
+
+ while (BlocksRemaining > 0) {
+
+ if (BlocksRemaining <= MaxBlock) {
+
+ SectorCount = (UINT16) BlocksRemaining;
+ } else {
+
+ SectorCount = MaxBlock;
+ }
+
+ ByteCount = SectorCount * BlockSize;
+ Timeout = EfiScsiStallSeconds (2);
+
+ MaxRetry = 2;
+ for (Index = 0; Index < MaxRetry; Index++) {
+
+ Status = ScsiDiskRead10 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ Lba32,
+ SectorCount
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (!NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ }
+
+ if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // actual transferred sectors
+ //
+ SectorCount = ByteCount / BlockSize;
+
+ Lba32 += SectorCount;
+ PtrBuffer = PtrBuffer + SectorCount * BlockSize;
+ BlocksRemaining -= SectorCount;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScsiDiskWriteSectors (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ VOID *Buffer,
+ EFI_LBA Lba,
+ UINTN NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Buffer - TODO: add argument description
+ Lba - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UINTN BlocksRemaining;
+ UINT32 Lba32;
+ UINT8 *PtrBuffer;
+ UINT32 BlockSize;
+ UINT32 ByteCount;
+ UINT32 MaxBlock;
+ UINT32 SectorCount;
+ UINT64 Timeout;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT8 MaxRetry;
+ BOOLEAN NeedRetry;
+ EFI_SCSI_SENSE_DATA *SenseData;
+ UINT8 SenseDataLength;
+ UINTN NumberOfSenseKeys;
+
+ SenseData = NULL;
+ SenseDataLength = 0;
+ NumberOfSenseKeys = 0;
+
+ Status = EFI_SUCCESS;
+
+ BlocksRemaining = NumberOfBlocks;
+ BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
+ //
+ // limit the data bytes that can be transferred by one Write(10) Command
+ //
+ MaxBlock = 65536;
+
+ PtrBuffer = Buffer;
+ Lba32 = (UINT32) Lba;
+
+ while (BlocksRemaining > 0) {
+
+ if (BlocksRemaining <= MaxBlock) {
+
+ SectorCount = (UINT16) BlocksRemaining;
+ } else {
+
+ SectorCount = MaxBlock;
+ }
+
+ ByteCount = SectorCount * BlockSize;
+ Timeout = EfiScsiStallSeconds (2);
+ MaxRetry = 2;
+ for (Index = 0; Index < MaxRetry; Index++) {
+ Status = ScsiDiskWrite10 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ Lba32,
+ SectorCount
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (!NeedRetry) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // actual transferred sectors
+ //
+ SectorCount = ByteCount / BlockSize;
+
+ Lba32 += SectorCount;
+ PtrBuffer = PtrBuffer + SectorCount * BlockSize;
+ BlocksRemaining -= SectorCount;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ScsiDiskRead10 (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ UINT64 Timeout,
+ UINT8 *DataBuffer,
+ UINT32 *DataLength,
+ UINT32 StartLba,
+ UINT32 SectorSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Timeout - TODO: add argument description
+ DataBuffer - TODO: add argument description
+ DataLength - TODO: add argument description
+ StartLba - TODO: add argument description
+ SectorSize - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ UINT8 SenseDataLength;
+ EFI_STATUS Status;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ *NeedRetry = FALSE;
+ *NumberOfSenseKeys = 0;
+ SenseDataLength = 0;
+ Status = SubmitRead10Command (
+ ScsiDiskDevice->ScsiIo,
+ Timeout,
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ DataBuffer,
+ DataLength,
+ StartLba,
+ SectorSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+ScsiDiskWrite10 (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ UINT64 Timeout,
+ UINT8 *DataBuffer,
+ UINT32 *DataLength,
+ UINT32 StartLba,
+ UINT32 SectorSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Timeout - TODO: add argument description
+ DataBuffer - TODO: add argument description
+ DataLength - TODO: add argument description
+ StartLba - TODO: add argument description
+ SectorSize - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ *NeedRetry = FALSE;
+ *NumberOfSenseKeys = 0;
+ SenseDataLength = 0;
+ Status = SubmitWrite10Command (
+ ScsiDiskDevice->ScsiIo,
+ Timeout,
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ DataBuffer,
+ DataLength,
+ StartLba,
+ SectorSize
+ );
+ return Status;
+}
+
+BOOLEAN
+ScsiDiskIsNoMedia (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsNoMedia;
+
+ IsNoMedia = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ //
+ // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),
+ // Additional Sense Code is ASC_NO_MEDIA (0x3A)
+ //
+ if ((SensePtr->Sense_Key == EFI_SCSI_SK_NOT_READY) &&
+ (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_NO_MEDIA)) {
+ IsNoMedia = TRUE;
+ }
+
+ SensePtr++;
+ }
+
+ return IsNoMedia;
+}
+
+BOOLEAN
+ScsiDiskIsMediaError (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsError;
+
+ IsError = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ switch (SensePtr->Sense_Key) {
+
+ case EFI_SCSI_SK_MEDIUM_ERROR:
+ //
+ // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)
+ //
+ switch (SensePtr->Addnl_Sense_Code) {
+
+ //
+ // fall through
+ //
+ case EFI_SCSI_ASC_MEDIA_ERR1:
+
+ //
+ // fall through
+ //
+ case EFI_SCSI_ASC_MEDIA_ERR2:
+
+ //
+ // fall through
+ //
+ case EFI_SCSI_ASC_MEDIA_ERR3:
+ case EFI_SCSI_ASC_MEDIA_ERR4:
+ IsError = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case EFI_SCSI_SK_NOT_READY:
+ //
+ // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
+ //
+ switch (SensePtr->Addnl_Sense_Code) {
+ //
+ // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)
+ //
+ case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN:
+ IsError = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ SensePtr++;
+ }
+
+ return IsError;
+}
+
+BOOLEAN
+ScsiDiskIsHardwareError (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsError;
+
+ IsError = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ //
+ // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)
+ //
+ if (SensePtr->Sense_Key == EFI_SCSI_SK_HARDWARE_ERROR) {
+ IsError = TRUE;
+ }
+
+ SensePtr++;
+ }
+
+ return IsError;
+}
+
+BOOLEAN
+ScsiDiskIsMediaChange (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsMediaChanged;
+
+ IsMediaChanged = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+ //
+ // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),
+ // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)
+ //
+ if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&
+ (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_MEDIA_CHANGE)) {
+ IsMediaChanged = TRUE;
+ }
+
+ SensePtr++;
+ }
+
+ return IsMediaChanged;
+}
+
+BOOLEAN
+ScsiDiskIsResetBefore (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsResetBefore;
+
+ IsResetBefore = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ //
+ // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)
+ // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)
+ //
+ if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&
+ (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_RESET)) {
+ IsResetBefore = TRUE;
+ }
+
+ SensePtr++;
+ }
+
+ return IsResetBefore;
+}
+
+BOOLEAN
+ScsiDiskIsDriveReady (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts,
+ OUT BOOLEAN *RetryLater
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+ RetryLater - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN IsReady;
+
+ IsReady = TRUE;
+ *RetryLater = FALSE;
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ switch (SensePtr->Sense_Key) {
+
+ case EFI_SCSI_SK_NOT_READY:
+ //
+ // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
+ //
+ switch (SensePtr->Addnl_Sense_Code) {
+ case EFI_SCSI_ASC_NOT_READY:
+ //
+ // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)
+ //
+ switch (SensePtr->Addnl_Sense_Code_Qualifier) {
+ case EFI_SCSI_ASCQ_IN_PROGRESS:
+ //
+ // Additional Sense Code Qualifier is
+ // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)
+ //
+ IsReady = FALSE;
+ *RetryLater = TRUE;
+ break;
+
+ default:
+ IsReady = FALSE;
+ *RetryLater = FALSE;
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ SensePtr++;
+ }
+
+ return IsReady;
+}
+
+BOOLEAN
+ScsiDiskHaveSenseKey (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ EFI_SCSI_SENSE_DATA *SensePtr;
+ UINTN Index;
+ BOOLEAN HaveSenseKey;
+
+ if (SenseCounts == 0) {
+ HaveSenseKey = FALSE;
+ } else {
+ HaveSenseKey = TRUE;
+ }
+
+ SensePtr = SenseData;
+
+ for (Index = 0; Index < SenseCounts; Index++) {
+
+ //
+ // Sense Key is SK_NO_SENSE (0x0)
+ //
+ if ((SensePtr->Sense_Key == EFI_SCSI_SK_NO_SENSE) &&
+ (Index == 0)) {
+ HaveSenseKey = FALSE;
+ }
+
+ SensePtr++;
+ }
+
+ return HaveSenseKey;
+}
+
+VOID
+ReleaseScsiDiskDeviceResources (
+ IN SCSI_DISK_DEV *ScsiDiskDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ if (ScsiDiskDevice == NULL) {
+ return ;
+ }
+
+ if (ScsiDiskDevice->SenseData != NULL) {
+ gBS->FreePool (ScsiDiskDevice->SenseData);
+ ScsiDiskDevice->SenseData = NULL;
+ }
+
+ if (ScsiDiskDevice->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (ScsiDiskDevice->ControllerNameTable);
+ ScsiDiskDevice->ControllerNameTable = NULL;
+ }
+
+ gBS->FreePool (ScsiDiskDevice);
+
+ ScsiDiskDevice = NULL;
+}
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h
new file mode 100644
index 0000000000..96d1da4f90
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.h
@@ -0,0 +1,728 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ScsiDisk.h
+
+Abstract:
+
+ Header file for SCSI Disk Driver.
+
+--*/
+
+#ifndef _SCSI_DISK_H
+#define _SCSI_DISK_H
+
+
+#include <IndustryStandard/scsi.h>
+
+#define IsDeviceFixed(a) (a)->FixedDevice ? 1 : 0
+
+#define SCSI_DISK_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'c', 'd', 'k')
+
+typedef struct {
+ UINT32 Signature;
+
+ EFI_HANDLE Handle;
+
+ EFI_BLOCK_IO_PROTOCOL BlkIo;
+ EFI_BLOCK_IO_MEDIA BlkIoMedia;
+ EFI_SCSI_IO_PROTOCOL *ScsiIo;
+ UINT8 DeviceType;
+ BOOLEAN FixedDevice;
+ UINT16 Reserved;
+
+ EFI_SCSI_SENSE_DATA *SenseData;
+ UINTN SenseDataNumber;
+ EFI_SCSI_INQUIRY_DATA InquiryData;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} SCSI_DISK_DEV;
+
+#define SCSI_DISK_DEV_FROM_THIS(a) CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gScsiDiskComponentName;
+//
+// action code used in detect media process
+//
+#define ACTION_NO_ACTION 0x00
+#define ACTION_READ_CAPACITY 0x01
+#define ACTION_RETRY_COMMAND_LATER 0x02
+
+EFI_STATUS
+EFIAPI
+ScsiDiskReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ ExtendedVerification - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiDiskReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ LBA - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiDiskWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ MediaId - TODO: add argument description
+ LBA - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+ScsiDiskFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskDetectMedia (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN MustReadCap,
+ BOOLEAN *MediaChange
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ MustReadCap - TODO: add argument description
+ MediaChange - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskTestUnitReady (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+DetectMediaParsingSenseKeys (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ EFI_SCSI_SENSE_DATA *SenseData,
+ UINTN NumberOfSenseKeys,
+ UINTN *Action
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ SenseData - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Action - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskReadCapacity (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CheckHostAdapterStatus (
+ UINT8 HostAdapterStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ HostAdapterStatus - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+CheckTargetStatus (
+ UINT8 TargetStatus
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ TargetStatus - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskRequestSenseKeys (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ BOOLEAN AskResetIfError
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ AskResetIfError - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskInquiryDevice (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+ParseInquiryData (
+ SCSI_DISK_DEV *ScsiDiskDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskReadSectors (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ VOID *Buffer,
+ EFI_LBA Lba,
+ UINTN NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Buffer - TODO: add argument description
+ Lba - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskWriteSectors (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ VOID *Buffer,
+ EFI_LBA Lba,
+ UINTN NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Buffer - TODO: add argument description
+ Lba - TODO: add argument description
+ NumberOfBlocks - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskRead10 (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ UINT64 Timeout,
+ UINT8 *DataBuffer,
+ UINT32 *DataLength,
+ UINT32 StartLba,
+ UINT32 SectorSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Timeout - TODO: add argument description
+ DataBuffer - TODO: add argument description
+ DataLength - TODO: add argument description
+ StartLba - TODO: add argument description
+ SectorSize - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+ScsiDiskWrite10 (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ BOOLEAN *NeedRetry,
+ EFI_SCSI_SENSE_DATA **SenseDataArray,
+ UINTN *NumberOfSenseKeys,
+ UINT64 Timeout,
+ UINT8 *DataBuffer,
+ UINT32 *DataLength,
+ UINT32 StartLba,
+ UINT32 SectorSize
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ NeedRetry - TODO: add argument description
+ SenseDataArray - TODO: add argument description
+ NumberOfSenseKeys - TODO: add argument description
+ Timeout - TODO: add argument description
+ DataBuffer - TODO: add argument description
+ DataLength - TODO: add argument description
+ StartLba - TODO: add argument description
+ SectorSize - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+GetMediaInfo (
+ SCSI_DISK_DEV *ScsiDiskDevice,
+ EFI_SCSI_DISK_CAPACITY_DATA *Capacity
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+ Capacity - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsNoMedia (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsMediaError (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsHardwareError (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsMediaChange (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsResetBefore (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskIsDriveReady (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts,
+ OUT BOOLEAN *NeedRetry
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+ NeedRetry - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+ScsiDiskHaveSenseKey (
+ IN EFI_SCSI_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ SenseData - TODO: add argument description
+ SenseCounts - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+ReleaseScsiDiskDeviceResources (
+ IN SCSI_DISK_DEV *ScsiDiskDevice
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ScsiDiskDevice - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd
new file mode 100644
index 0000000000..ec19f96872
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.mbd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>ScsiDisk</BaseName>
+ <Guid>0A66E322-3740-4cce-AD62-BD172CECCA35</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:18</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>UefiMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>UefiDriverModelLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>EdkDxePrintLib</Library>
+ <Library>BaseLib</Library>
+ <Library>EdkScsiLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ </Libraries>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa
new file mode 100644
index 0000000000..d81af71b53
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>ScsiDisk</BaseName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <ComponentType>BS_DRIVER</ComponentType>
+ <Guid>0A66E322-3740-4cce-AD62-BD172CECCA35</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for Scsi Disk module.Revision History</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:18</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkScsiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>ScsiDisk.h</Filename>
+ <Filename>ScsiDisk.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="TO_START">ScsiIo</Protocol>
+ <Protocol Usage="BY_START">BlockIo</Protocol>
+ </Protocols>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint></ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <DriverBinding>gScsiDiskDriverBinding</DriverBinding>
+ <ComponentName>gScsiDiskComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml
new file mode 100644
index 0000000000..5d5f4d83b7
--- /dev/null
+++ b/EdkModulePkg/Bus/Scsi/ScsiDisk/Dxe/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<project basedir="." default="ScsiDisk"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Bus\Scsi\ScsiDisk\Dxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="ScsiDisk">
+ <GenBuild baseName="ScsiDisk" mbdFilename="${MODULE_DIR}\ScsiDisk.mbd" msaFilename="${MODULE_DIR}\ScsiDisk.msa"/>
+ </target>
+ <target depends="ScsiDisk_clean" name="clean"/>
+ <target depends="ScsiDisk_cleanall" name="cleanall"/>
+ <target name="ScsiDisk_clean">
+ <OutputDirSetup baseName="ScsiDisk" mbdFilename="${MODULE_DIR}\ScsiDisk.mbd" msaFilename="${MODULE_DIR}\ScsiDisk.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\ScsiDisk_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\ScsiDisk_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="ScsiDisk_cleanall">
+ <OutputDirSetup baseName="ScsiDisk" mbdFilename="${MODULE_DIR}\ScsiDisk.mbd" msaFilename="${MODULE_DIR}\ScsiDisk.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\ScsiDisk_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\ScsiDisk_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**ScsiDisk*"/>
+ </delete>
+ </target>
+</project> \ No newline at end of file