summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-22 15:55:38 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:14:37 +0800
commit7f05fa00f73038b425002566d3afe6c3ade2ccdb (patch)
tree297e208d4ade33a8bb3d5d20f72c53e0d134e003 /MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
parented2ecce34b3830562c4239093a41ba92d76d5f31 (diff)
downloadedk2-platforms-7f05fa00f73038b425002566d3afe6c3ade2ccdb.tar.xz
MdeModulePkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c')
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c1512
1 files changed, 0 insertions, 1512 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c b/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
deleted file mode 100644
index 0802b61726..0000000000
--- a/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
+++ /dev/null
@@ -1,1512 +0,0 @@
-/** @file
- SCSI Bus driver that layers on every SCSI Pass Thru and
- Extended SCSI Pass Thru protocol in the system.
-
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-
-#include "ScsiBus.h"
-
-
-EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {
- SCSIBusDriverBindingSupported,
- SCSIBusDriverBindingStart,
- SCSIBusDriverBindingStop,
- 0xa,
- NULL,
- NULL
-};
-
-VOID *mWorkingBuffer;
-
-/**
- Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.
-
- @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET
- @param CommandPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
-
-**/
-EFI_STATUS
-EFIAPI
-ScsiioToPassThruPacket (
- IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,
- OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket
- );
-
-/**
- Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.
-
- @param ScsiPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
- @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET
-
-**/
-EFI_STATUS
-EFIAPI
-PassThruToScsiioPacket (
- IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,
- OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet
- );
-
-/**
- Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0
- SCSI IO Packet.
-
- @param Event The instance of EFI_EVENT.
- @param Context The parameter passed in.
-
-**/
-VOID
-EFIAPI
-NotifyFunction (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-/**
- Allocates an aligned buffer for SCSI device.
-
- This function allocates an aligned buffer for the SCSI device to perform
- SCSI pass through operations. The alignment requirement is from SCSI pass
- through interface.
-
- @param ScsiIoDevice The SCSI child device involved for the operation.
- @param BufferSize The request buffer size.
-
- @return A pointer to the aligned buffer or NULL if the allocation fails.
-
-**/
-VOID *
-AllocateAlignedBuffer (
- IN SCSI_IO_DEV *ScsiIoDevice,
- IN UINTN BufferSize
- )
-{
- return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiIoDevice->ScsiIo.IoAlign);
-}
-
-/**
- Frees an aligned buffer for SCSI device.
-
- This function frees an aligned buffer for the SCSI device to perform
- SCSI pass through operations.
-
- @param Buffer The aligned buffer to be freed.
- @param BufferSize The request buffer size.
-
-**/
-VOID
-FreeAlignedBuffer (
- IN VOID *Buffer,
- IN UINTN BufferSize
- )
-{
- if (Buffer != NULL) {
- FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));
- }
-}
-
-/**
- The user Entry Point for module ScsiBus. The user code starts with this function.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-InitializeScsiBus(
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- //
- // Install driver model protocol(s).
- //
- Status = EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gSCSIBusDriverBinding,
- ImageHandle,
- &gScsiBusComponentName,
- &gScsiBusComponentName2
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
-
-
-/**
- Test to see if this driver supports ControllerHandle.
-
- This service is called by the EFI boot service ConnectController(). In order
- to make drivers as small as possible, there are a few calling restrictions for
- this service. ConnectController() must follow these calling restrictions. If
- any other agent wishes to call Supported() it must also follow these calling
- restrictions.
-
- @param This Protocol instance pointer.
- @param ControllerHandle Handle of device to test
- @param RemainingDevicePath Optional parameter use to pick a specific child
- device to start.
-
- @retval EFI_SUCCESS This driver supports this device
- @retval EFI_ALREADY_STARTED This driver is already running on this device
- @retval other This driver does not support this device
-
-**/
-EFI_STATUS
-EFIAPI
-SCSIBusDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- EFI_STATUS Status;
- EFI_SCSI_PASS_THRU_PROTOCOL *PassThru;
- EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;
- UINT64 Lun;
- UINT8 *TargetId;
- SCSI_TARGET_ID ScsiTargetId;
-
- TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];
- SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
-
- //
- // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as
- // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly
- // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- (VOID **)&ExtPassThru,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- } else if (!EFI_ERROR(Status)) {
- //
- // Check if RemainingDevicePath is NULL or the End of Device Path Node,
- // if yes, return EFI_SUCCESS.
- //
- if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) {
- //
- // Close protocol regardless of RemainingDevicePath validation
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- return EFI_SUCCESS;
- } else {
- //
- // If RemainingDevicePath isn't the End of Device Path Node, check its validation
- //
- Status = ExtPassThru->GetTargetLun (ExtPassThru, RemainingDevicePath, &TargetId, &Lun);
- //
- // Close protocol regardless of RemainingDevicePath validation
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- if (!EFI_ERROR(Status)) {
- return EFI_SUCCESS;
- }
- }
- }
-
- //
- // Come here in 2 condition:
- // 1. ExtPassThru doesn't exist.
- // 2. ExtPassThru exists but RemainingDevicePath is invalid.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- (VOID **)&PassThru,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Test RemainingDevicePath is valid or not.
- //
- if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
- Status = PassThru->GetTargetLun (PassThru, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- return Status;
-}
-
-
-/**
- Start this driver on ControllerHandle.
-
- This service is called by the EFI boot service ConnectController(). In order
- to make drivers as small as possible, there are a few calling restrictions for
- this service. ConnectController() must follow these calling restrictions. If
- any other agent wishes to call Start() it must also follow these calling
- restrictions.
-
- @param This Protocol instance pointer.
- @param ControllerHandle Handle of device to bind driver to
- @param RemainingDevicePath Optional parameter use to pick a specific child
- device to start.
-
- @retval EFI_SUCCESS This driver is added to ControllerHandle
- @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
- @retval other This driver does not support this device
-
-**/
-EFI_STATUS
-EFIAPI
-SCSIBusDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- UINT64 Lun;
- UINT8 *TargetId;
- BOOLEAN ScanOtherPuns;
- BOOLEAN FromFirstTarget;
- BOOLEAN ExtScsiSupport;
- EFI_STATUS Status;
- EFI_STATUS DevicePathStatus;
- EFI_STATUS PassThruStatus;
- SCSI_BUS_DEVICE *ScsiBusDev;
- SCSI_TARGET_ID ScsiTargetId;
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_SCSI_PASS_THRU_PROTOCOL *ScsiInterface;
- EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiInterface;
- EFI_SCSI_BUS_PROTOCOL *BusIdentify;
-
- TargetId = NULL;
- ScanOtherPuns = TRUE;
- FromFirstTarget = FALSE;
- ExtScsiSupport = FALSE;
- PassThruStatus = EFI_SUCCESS;
-
- TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];
- SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
-
- DevicePathStatus = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ParentDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (DevicePathStatus) && (DevicePathStatus != EFI_ALREADY_STARTED)) {
- return DevicePathStatus;
- }
-
- //
- // Report Status Code to indicate SCSI bus starts
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),
- ParentDevicePath
- );
-
- //
- // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as
- // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly
- // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- (VOID **) &ExtScsiInterface,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- //
- // Fail to open UEFI ExtendPassThru Protocol, then try to open EFI PassThru Protocol instead.
- //
- if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- (VOID **) &ScsiInterface,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- //
- // Fail to open EFI PassThru Protocol, Close the DevicePathProtocol if it is opened by this time.
- //
- if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
- if (!EFI_ERROR(DevicePathStatus)) {
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
- return Status;
- }
- } else {
- //
- // Succeed to open ExtPassThru Protocol, and meanwhile open PassThru Protocol
- // with BY_DRIVER if it is also present on the handle. The intent is to prevent
- // another SCSI Bus Driver to work on the same host handle.
- //
- ExtScsiSupport = TRUE;
- PassThruStatus = gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- (VOID **) &ScsiInterface,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- }
-
- if (Status != EFI_ALREADY_STARTED) {
- //
- // Go through here means either ExtPassThru or PassThru Protocol is successfully opened
- // on this handle for this time. Then construct Host controller private data.
- //
- ScsiBusDev = NULL;
- ScsiBusDev = AllocateZeroPool(sizeof(SCSI_BUS_DEVICE));
- if (ScsiBusDev == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
- ScsiBusDev->Signature = SCSI_BUS_DEVICE_SIGNATURE;
- ScsiBusDev->ExtScsiSupport = ExtScsiSupport;
- ScsiBusDev->DevicePath = ParentDevicePath;
- if (ScsiBusDev->ExtScsiSupport) {
- ScsiBusDev->ExtScsiInterface = ExtScsiInterface;
- } else {
- ScsiBusDev->ScsiInterface = ScsiInterface;
- }
-
- //
- // Install EFI_SCSI_BUS_PROTOCOL to the controller handle, So ScsiBusDev could be
- // retrieved on this controller handle. With ScsiBusDev, we can know which PassThru
- // Protocol is present on the handle, UEFI ExtPassThru Protocol or EFI PassThru Protocol.
- //
- Status = gBS->InstallProtocolInterface (
- &Controller,
- &gEfiCallerIdGuid,
- EFI_NATIVE_INTERFACE,
- &ScsiBusDev->BusIdentify
- );
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
- } else {
- //
- // Go through here means Start() is re-invoked again, nothing special is required to do except
- // picking up Host controller private information.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiCallerIdGuid,
- (VOID **) &BusIdentify,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
- ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);
- }
-
- //
- // Report Status Code to indicate detecting devices on bus
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),
- ParentDevicePath
- );
-
- Lun = 0;
- if (RemainingDevicePath == NULL) {
- //
- // If RemainingDevicePath is NULL,
- // must enumerate all SCSI devices anyway
- //
- FromFirstTarget = TRUE;
- } else if (!IsDevicePathEnd (RemainingDevicePath)) {
- //
- // If RemainingDevicePath isn't the End of Device Path Node,
- // only scan the specified device by RemainingDevicePath
- //
- if (ScsiBusDev->ExtScsiSupport) {
- Status = ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);
- } else {
- Status = ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- //
- // If RemainingDevicePath is the End of Device Path Node,
- // skip enumerate any device and return EFI_SUCESSS
- //
- ScanOtherPuns = FALSE;
- }
-
- while(ScanOtherPuns) {
- if (FromFirstTarget) {
- //
- // Remaining Device Path is NULL, scan all the possible Puns in the
- // SCSI Channel.
- //
- if (ScsiBusDev->ExtScsiSupport) {
- Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);
- } else {
- Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId.ScsiId.Scsi, &Lun);
- }
- if (EFI_ERROR (Status)) {
- //
- // no legal Pun and Lun found any more
- //
- break;
- }
- } else {
- ScanOtherPuns = FALSE;
- }
- //
- // Avoid creating handle for the host adapter.
- //
- if (ScsiBusDev->ExtScsiSupport) {
- if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {
- continue;
- }
- } else {
- if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ScsiInterface->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, &ScsiTargetId, Lun, ScsiBusDev);
- }
- return EFI_SUCCESS;
-
-ErrorExit:
-
- if (ScsiBusDev != NULL) {
- FreePool (ScsiBusDev);
- }
-
- if (ExtScsiSupport) {
- gBS->CloseProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- if (!EFI_ERROR (PassThruStatus)) {
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
- return Status;
-}
-
-/**
- Stop this driver on ControllerHandle.
-
- This service is called by the EFI boot service DisconnectController().
- In order to make drivers as small as possible, there are a few calling
- restrictions for this service. DisconnectController() must follow these
- calling restrictions. If any other agent wishes to call Stop() it must also
- follow these calling restrictions.
-
- @param This Protocol instance pointer.
- @param ControllerHandle Handle of device to stop driver on
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
- children is zero stop the entire bus driver.
- @param ChildHandleBuffer List of Child Handles to Stop.
-
- @retval EFI_SUCCESS This driver is removed ControllerHandle
- @retval other This driver was not removed from this device
-
-**/
-EFI_STATUS
-EFIAPI
-SCSIBusDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
-{
- EFI_STATUS Status;
- BOOLEAN AllChildrenStopped;
- UINTN Index;
- EFI_SCSI_IO_PROTOCOL *ScsiIo;
- SCSI_IO_DEV *ScsiIoDevice;
- VOID *ScsiPassThru;
- EFI_SCSI_BUS_PROTOCOL *Scsidentifier;
- SCSI_BUS_DEVICE *ScsiBusDev;
-
- if (NumberOfChildren == 0) {
- //
- // Get the SCSI_BUS_DEVICE
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiCallerIdGuid,
- (VOID **) &Scsidentifier,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (Scsidentifier);
-
- //
- // Uninstall SCSI Bus Protocol
- //
- gBS->UninstallProtocolInterface (
- Controller,
- &gEfiCallerIdGuid,
- &ScsiBusDev->BusIdentify
- );
-
- //
- // Close the bus driver
- //
- if (ScsiBusDev->ExtScsiSupport) {
- //
- // Close ExtPassThru Protocol from this controller handle
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- //
- // When Start() succeeds to open ExtPassThru, it always tries to open PassThru BY_DRIVER.
- // Its intent is to prevent another SCSI Bus Driver from woking on the same host handle.
- // So Stop() needs to try to close PassThru if present here.
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- FreePool (ScsiBusDev);
- 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
- //
- if (ScsiIoDevice->ExtScsiSupport) {
- Status = gBS->CloseProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- This->DriverBindingHandle,
- ChildHandleBuffer[Index]
- );
-
- } else {
- 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;
- if (ScsiIoDevice->ExtScsiSupport) {
- gBS->OpenProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- &ScsiPassThru,
- This->DriverBindingHandle,
- ChildHandleBuffer[Index],
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- } else {
- gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- &ScsiPassThru,
- This->DriverBindingHandle,
- ChildHandleBuffer[Index],
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- }
- } else {
- FreePool (ScsiIoDevice);
- }
- }
-
- if (!AllChildrenStopped) {
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Retrieves the device type information of the SCSI Controller.
-
- @param This Protocol instance pointer.
- @param DeviceType A pointer to the device type information retrieved from
- the SCSI Controller.
-
- @retval EFI_SUCCESS Retrieves the device type information successfully.
- @retval EFI_INVALID_PARAMETER The DeviceType is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-ScsiGetDeviceType (
- IN EFI_SCSI_IO_PROTOCOL *This,
- OUT UINT8 *DeviceType
- )
-{
- SCSI_IO_DEV *ScsiIoDevice;
-
- if (DeviceType == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
- *DeviceType = ScsiIoDevice->ScsiDeviceType;
- return EFI_SUCCESS;
-}
-
-
-/**
- Retrieves the device location in the SCSI channel.
-
- @param This Protocol instance pointer.
- @param Target A pointer to the Target ID of a SCSI device
- on the SCSI channel.
- @param Lun A pointer to the LUN of the SCSI device on
- the SCSI channel.
-
- @retval EFI_SUCCESS Retrieves the device location successfully.
- @retval EFI_INVALID_PARAMETER The Target or Lun is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-ScsiGetDeviceLocation (
- IN EFI_SCSI_IO_PROTOCOL *This,
- IN OUT UINT8 **Target,
- OUT UINT64 *Lun
- )
-{
- SCSI_IO_DEV *ScsiIoDevice;
-
- if (Target == NULL || Lun == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
-
- CopyMem (*Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);
-
- *Lun = ScsiIoDevice->Lun;
-
- return EFI_SUCCESS;
-}
-
-/**
- Resets the SCSI Bus that the SCSI Controller is attached to.
-
- @param This Protocol instance pointer.
-
- @retval EFI_SUCCESS The SCSI bus is reset successfully.
- @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus.
- @retval EFI_UNSUPPORTED The bus reset operation is not supported by the
- SCSI Host Controller.
- @retval EFI_TIMEOUT A timeout occurred while attempting to reset
- the SCSI bus.
-**/
-EFI_STATUS
-EFIAPI
-ScsiResetBus (
- IN EFI_SCSI_IO_PROTOCOL *This
- )
-{
- SCSI_IO_DEV *ScsiIoDevice;
-
- ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
-
- //
- // Report Status Code to indicate reset happens
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
- ScsiIoDevice->ScsiBusDeviceData->DevicePath
- );
-
- if (ScsiIoDevice->ExtScsiSupport){
- return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);
- } else {
- return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);
- }
-}
-
-
-/**
- Resets the SCSI Controller that the device handle specifies.
-
- @param This Protocol instance pointer.
-
- @retval EFI_SUCCESS Reset the SCSI controller successfully.
- @retval EFI_DEVICE_ERROR Errors are encountered when resetting the SCSI Controller.
- @retval EFI_UNSUPPORTED The SCSI bus does not support a device reset operation.
- @retval EFI_TIMEOUT A timeout occurred while attempting to reset the
- SCSI Controller.
-**/
-EFI_STATUS
-EFIAPI
-ScsiResetDevice (
- IN EFI_SCSI_IO_PROTOCOL *This
- )
-{
- SCSI_IO_DEV *ScsiIoDevice;
- UINT8 Target[TARGET_MAX_BYTES];
-
- ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
-
- //
- // Report Status Code to indicate reset happens
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
- ScsiIoDevice->ScsiBusDeviceData->DevicePath
- );
-
- CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);
-
-
- if (ScsiIoDevice->ExtScsiSupport) {
- return ScsiIoDevice->ExtScsiPassThru->ResetTargetLun (
- ScsiIoDevice->ExtScsiPassThru,
- Target,
- ScsiIoDevice->Lun
- );
- } else {
- return ScsiIoDevice->ScsiPassThru->ResetTarget (
- ScsiIoDevice->ScsiPassThru,
- ScsiIoDevice->Pun.ScsiId.Scsi,
- ScsiIoDevice->Lun
- );
- }
-}
-
-
-/**
- Sends a SCSI Request Packet to the SCSI Controller for execution.
-
- @param This Protocol instance pointer.
- @param CommandPacket The SCSI request packet to send to the SCSI
- Controller specified by the device handle.
- @param 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.
-
- @retval 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.
- @retval EFI_BAD_BUFFER_SIZE 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.
- @retval 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.
- @retval 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.
- @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid.
- The SCSI Request Packet was not sent, so no
- additional status information is available.
- @retval 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.
- @retval 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.
-**/
-EFI_STATUS
-EFIAPI
-ScsiExecuteSCSICommand (
- IN EFI_SCSI_IO_PROTOCOL *This,
- IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,
- IN EFI_EVENT Event OPTIONAL
- )
-{
- SCSI_IO_DEV *ScsiIoDevice;
- EFI_STATUS Status;
- UINT8 Target[TARGET_MAX_BYTES];
- EFI_EVENT PacketEvent;
- EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ExtRequestPacket;
- SCSI_EVENT_DATA EventData;
-
- PacketEvent = NULL;
-
- if (Packet == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
- CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);
-
- if (ScsiIoDevice->ExtScsiSupport) {
- ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;
-
- if (((ScsiIoDevice->ExtScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event != NULL)) {
- Status = ScsiIoDevice->ExtScsiPassThru->PassThru (
- ScsiIoDevice->ExtScsiPassThru,
- Target,
- ScsiIoDevice->Lun,
- ExtRequestPacket,
- Event
- );
- } else {
- //
- // If there's no event or the SCSI Device doesn't support NON-BLOCKING,
- // let the 'Event' parameter for PassThru() be NULL.
- //
- Status = ScsiIoDevice->ExtScsiPassThru->PassThru (
- ScsiIoDevice->ExtScsiPassThru,
- Target,
- ScsiIoDevice->Lun,
- ExtRequestPacket,
- NULL
- );
- if ((!EFI_ERROR(Status)) && (Event != NULL)) {
- //
- // Signal Event to tell caller to pick up the SCSI IO packet if the
- // PassThru() succeeds.
- //
- gBS->SignalEvent (Event);
- }
- }
- } else {
-
- mWorkingBuffer = AllocatePool (sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
-
- if (mWorkingBuffer == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Convert package into EFI1.0, EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.
- //
- Status = ScsiioToPassThruPacket(Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer);
- if (EFI_ERROR(Status)) {
- FreePool(mWorkingBuffer);
- return Status;
- }
-
- if (((ScsiIoDevice->ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event != NULL)) {
- EventData.Data1 = (VOID*)Packet;
- EventData.Data2 = Event;
- //
- // Create Event
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- NotifyFunction,
- &EventData,
- &PacketEvent
- );
- if (EFI_ERROR(Status)) {
- FreePool(mWorkingBuffer);
- return Status;
- }
-
- Status = ScsiIoDevice->ScsiPassThru->PassThru (
- ScsiIoDevice->ScsiPassThru,
- ScsiIoDevice->Pun.ScsiId.Scsi,
- ScsiIoDevice->Lun,
- mWorkingBuffer,
- PacketEvent
- );
-
- if (EFI_ERROR(Status)) {
- FreePool(mWorkingBuffer);
- gBS->CloseEvent(PacketEvent);
- return Status;
- }
-
- } else {
- //
- // If there's no event or SCSI Device doesn't support NON-BLOCKING, just convert
- // EFI1.0 PassThru packet back to UEFI2.0 SCSI IO Packet.
- //
- Status = ScsiIoDevice->ScsiPassThru->PassThru (
- ScsiIoDevice->ScsiPassThru,
- ScsiIoDevice->Pun.ScsiId.Scsi,
- ScsiIoDevice->Lun,
- mWorkingBuffer,
- NULL
- );
- if (EFI_ERROR(Status)) {
- FreePool(mWorkingBuffer);
- return Status;
- }
-
- PassThruToScsiioPacket((EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer,Packet);
- //
- // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,
- // free mWorkingBuffer.
- //
- FreePool(mWorkingBuffer);
-
- //
- // Signal Event to tell caller to pick up the SCSI IO Packet.
- //
- if (Event != NULL) {
- gBS->SignalEvent (Event);
- }
- }
- }
- return Status;
-}
-
-
-/**
- Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.
-
- @param This Protocol instance pointer
- @param Controller Controller handle
- @param TargetId Tartget to be scanned
- @param Lun The Lun of the SCSI device on the SCSI channel.
- @param ScsiBusDev The pointer of SCSI_BUS_DEVICE
-
- @retval EFI_SUCCESS Successfully to discover the device and attach
- ScsiIoProtocol to it.
- @retval EFI_OUT_OF_RESOURCES Fail to discover the device.
-
-**/
-EFI_STATUS
-EFIAPI
-ScsiScanCreateDevice (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN SCSI_TARGET_ID *TargetId,
- IN UINT64 Lun,
- IN OUT SCSI_BUS_DEVICE *ScsiBusDev
- )
-{
- EFI_STATUS Status;
- SCSI_IO_DEV *ScsiIoDevice;
- EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
- EFI_HANDLE DeviceHandle;
-
- DevicePath = NULL;
- RemainingDevicePath = NULL;
- ScsiDevicePath = NULL;
- ScsiIoDevice = NULL;
-
- //
- // Build Device Path
- //
- if (ScsiBusDev->ExtScsiSupport){
- Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (
- ScsiBusDev->ExtScsiInterface,
- &TargetId->ScsiId.ExtScsi[0],
- Lun,
- &ScsiDevicePath
- );
- } else {
- Status = ScsiBusDev->ScsiInterface->BuildDevicePath (
- ScsiBusDev->ScsiInterface,
- TargetId->ScsiId.Scsi,
- Lun,
- &ScsiDevicePath
- );
- }
-
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- DevicePath = AppendDevicePathNode (
- ScsiBusDev->DevicePath,
- ScsiDevicePath
- );
-
- if (DevicePath == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- DeviceHandle = NULL;
- RemainingDevicePath = DevicePath;
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
- if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
- //
- // The device has been started, directly return to fast boot.
- //
- Status = EFI_ALREADY_STARTED;
- goto ErrorExit;
- }
-
- ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));
- if (ScsiIoDevice == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;
- ScsiIoDevice->ScsiBusDeviceData = ScsiBusDev;
- CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);
- ScsiIoDevice->Lun = Lun;
-
- if (ScsiBusDev->ExtScsiSupport) {
- ScsiIoDevice->ExtScsiPassThru = ScsiBusDev->ExtScsiInterface;
- ScsiIoDevice->ExtScsiSupport = TRUE;
- ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ExtScsiPassThru->Mode->IoAlign;
-
- } else {
- ScsiIoDevice->ScsiPassThru = ScsiBusDev->ScsiInterface;
- ScsiIoDevice->ExtScsiSupport = FALSE;
- ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ScsiPassThru->Mode->IoAlign;
- }
-
- ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;
- ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;
- ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;
- ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;
- ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;
-
- //
- // Report Status Code here since the new SCSI device will be discovered
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),
- ScsiBusDev->DevicePath
- );
-
- if (!DiscoverScsiDevice (ScsiIoDevice)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- ScsiIoDevice->DevicePath = DevicePath;
-
- Status = gBS->InstallMultipleProtocolInterfaces (
- &ScsiIoDevice->Handle,
- &gEfiDevicePathProtocolGuid,
- ScsiIoDevice->DevicePath,
- &gEfiScsiIoProtocolGuid,
- &ScsiIoDevice->ScsiIo,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- } else {
- if (ScsiBusDev->ExtScsiSupport) {
- gBS->OpenProtocol (
- Controller,
- &gEfiExtScsiPassThruProtocolGuid,
- (VOID **) &(ScsiBusDev->ExtScsiInterface),
- This->DriverBindingHandle,
- ScsiIoDevice->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- } else {
- gBS->OpenProtocol (
- Controller,
- &gEfiScsiPassThruProtocolGuid,
- (VOID **) &(ScsiBusDev->ScsiInterface),
- This->DriverBindingHandle,
- ScsiIoDevice->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- }
- }
- return EFI_SUCCESS;
-
-ErrorExit:
-
- //
- // The memory space for ScsiDevicePath is allocated in
- // ScsiPassThru->BuildDevicePath() function; It is no longer used
- // after AppendDevicePathNode,so free the memory it occupies.
- //
- FreePool (ScsiDevicePath);
-
- if (DevicePath != NULL) {
- FreePool (DevicePath);
- }
-
- if (ScsiIoDevice != NULL) {
- FreePool (ScsiIoDevice);
- }
-
- return Status;
-}
-
-
-/**
- Discovery SCSI Device
-
- @param ScsiIoDevice The pointer of SCSI_IO_DEV
-
- @retval TRUE Find SCSI Device and verify it.
- @retval FALSE Unable to find SCSI Device.
-
-**/
-BOOLEAN
-DiscoverScsiDevice (
- IN OUT SCSI_IO_DEV *ScsiIoDevice
- )
-{
- EFI_STATUS Status;
- UINT32 InquiryDataLength;
- UINT8 SenseDataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
- EFI_SCSI_INQUIRY_DATA *InquiryData;
- UINT8 MaxRetry;
- UINT8 Index;
- BOOLEAN ScsiDeviceFound;
-
- HostAdapterStatus = 0;
- TargetStatus = 0;
-
- InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));
- if (InquiryData == NULL) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
-
- //
- // Using Inquiry command to scan for the device
- //
- InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
- SenseDataLength = 0;
- ZeroMem (InquiryData, InquiryDataLength);
-
- MaxRetry = 2;
- for (Index = 0; Index < MaxRetry; Index++) {
- Status = ScsiInquiryCommand (
- &ScsiIoDevice->ScsiIo,
- SCSI_BUS_TIMEOUT,
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- (VOID *) InquiryData,
- &InquiryDataLength,
- FALSE
- );
- if (!EFI_ERROR (Status)) {
- break;
- } else if ((Status == EFI_BAD_BUFFER_SIZE) ||
- (Status == EFI_INVALID_PARAMETER) ||
- (Status == EFI_UNSUPPORTED)) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
- }
-
- if (Index == MaxRetry) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
-
- //
- // Retrieved inquiry data successfully
- //
- if ((InquiryData->Peripheral_Qualifier != 0) &&
- (InquiryData->Peripheral_Qualifier != 3)) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
-
- if (InquiryData->Peripheral_Qualifier == 3) {
- if (InquiryData->Peripheral_Type != 0x1f) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
- }
-
- if (0x1e >= InquiryData->Peripheral_Type && InquiryData->Peripheral_Type >= 0xa) {
- ScsiDeviceFound = FALSE;
- goto Done;
- }
-
- //
- // 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 & 0x07);
- }
-
- ScsiDeviceFound = TRUE;
-
-Done:
- FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));
-
- return ScsiDeviceFound;
-}
-
-
-/**
- Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.
-
- @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET
- @param CommandPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
-
-**/
-EFI_STATUS
-EFIAPI
-ScsiioToPassThruPacket (
- IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,
- OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket
- )
-{
- //
- //EFI 1.10 doesn't support Bi-Direction Command.
- //
- if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL) {
- return EFI_UNSUPPORTED;
- }
-
- ZeroMem (CommandPacket, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
-
- CommandPacket->Timeout = Packet->Timeout;
- CommandPacket->Cdb = Packet->Cdb;
- CommandPacket->CdbLength = Packet->CdbLength;
- CommandPacket->DataDirection = Packet->DataDirection;
- CommandPacket->HostAdapterStatus = Packet->HostAdapterStatus;
- CommandPacket->TargetStatus = Packet->TargetStatus;
- CommandPacket->SenseData = Packet->SenseData;
- CommandPacket->SenseDataLength = Packet->SenseDataLength;
-
- if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {
- CommandPacket->DataBuffer = Packet->InDataBuffer;
- CommandPacket->TransferLength = Packet->InTransferLength;
- } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {
- CommandPacket->DataBuffer = Packet->OutDataBuffer;
- CommandPacket->TransferLength = Packet->OutTransferLength;
- }
- return EFI_SUCCESS;
-}
-
-
-/**
- Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.
-
- @param ScsiPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
- @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET
-
-**/
-EFI_STATUS
-EFIAPI
-PassThruToScsiioPacket (
- IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,
- OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet
- )
-{
- Packet->Timeout = ScsiPacket->Timeout;
- Packet->Cdb = ScsiPacket->Cdb;
- Packet->CdbLength = ScsiPacket->CdbLength;
- Packet->DataDirection = ScsiPacket->DataDirection;
- Packet->HostAdapterStatus = ScsiPacket->HostAdapterStatus;
- Packet->TargetStatus = ScsiPacket->TargetStatus;
- Packet->SenseData = ScsiPacket->SenseData;
- Packet->SenseDataLength = ScsiPacket->SenseDataLength;
-
- if (ScsiPacket->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {
- Packet->InDataBuffer = ScsiPacket->DataBuffer;
- Packet->InTransferLength = ScsiPacket->TransferLength;
- } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {
- Packet->OutDataBuffer = ScsiPacket->DataBuffer;
- Packet->OutTransferLength = ScsiPacket->TransferLength;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0
- SCSI IO Packet.
-
- @param Event The instance of EFI_EVENT.
- @param Context The parameter passed in.
-
-**/
-VOID
-EFIAPI
-NotifyFunction (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet;
- EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket;
- EFI_EVENT CallerEvent;
- SCSI_EVENT_DATA *PassData;
-
- PassData = (SCSI_EVENT_DATA*)Context;
- Packet = (EFI_SCSI_IO_SCSI_REQUEST_PACKET *)PassData->Data1;
- ScsiPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer;
-
- //
- // Convert EFI1.0 PassThru packet to UEFI2.0 SCSI IO Packet.
- //
- PassThruToScsiioPacket(ScsiPacket, Packet);
-
- //
- // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,
- // free mWorkingBuffer.
- //
- gBS->FreePool(mWorkingBuffer);
-
- //
- // Signal Event to tell caller to pick up UEFI2.0 SCSI IO Packet.
- //
- CallerEvent = PassData->Data2;
- gBS->CloseEvent(Event);
- gBS->SignalEvent(CallerEvent);
-}
-