4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "AtapiPassThru.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSCSI_COMMAND_SET gEndTable = { 0xff, (DATA_DIRECTION) 0xff };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync///
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/// This table contains all the supported ATAPI commands.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync///
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSCSI_COMMAND_SET gSupportedATAPICommands[] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_INQUIRY, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_LOAD_UNLOAD_CD, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_MECHANISM_STATUS, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_MODE_SELECT_10, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_MODE_SENSE_10, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PAUSE_RESUME, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PLAY_AUDIO_10, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PLAY_AUDIO_MSF, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PLAY_CD, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PLAY_CD_MSF, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_PREVENT_ALLOW_MEDIUM_REMOVAL,NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_10, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_12, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_CAPACITY, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_CD, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_CD_MSF, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_HEADER, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_SUB_CHANNEL, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_TOC, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_REQUEST_SENSE, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_SCAN, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_SEEK_10, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_SET_CD_SPEED, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_STOPPLAY_SCAN, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_START_STOP_UNIT, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_TEST_UNIT_READY, NoData },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_FORMAT_UNIT, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_READ_FORMAT_CAPACITIES, DataIn },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_VERIFY, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_WRITE_10, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_WRITE_12, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { OP_WRITE_AND_VERIFY, DataOut },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync { 0xff, (DATA_DIRECTION) 0xff }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_MODE gScsiPassThruMode = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"ATAPI Controller",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"ATAPI Channel",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_PROTOCOL gScsiPassThruProtocolTemplate = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gScsiPassThruMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruFunction,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruGetNextDevice,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruBuildDevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruGetTargetLun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruResetChannel,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruResetTarget
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_MODE gExtScsiPassThruMode = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_PROTOCOL gExtScsiPassThruProtocolTemplate = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gExtScsiPassThruMode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruFunction,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruGetNextTargetLun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruBuildDevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruGetTargetLun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruResetChannel,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruResetTarget,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiExtScsiPassThruGetNextTarget
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruDriverBindingSupported,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruDriverBindingStart,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPassThruDriverBindingStop,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x10,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruDriverBindingSupported (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Test to see if this driver supports ControllerHandle. Any ControllerHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync that has gEfiPciIoProtocolGuid installed and is IDE Controller it will be supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller - Handle of device to test
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemainingDevicePath - Not used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PROTOCOL *PciIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PCI_TYPE00 Pci;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the IO Abstraction(s) needed to perform the supported test
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_DRIVER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use the PCI I/O Protocol to see if Controller is a IDE Controller that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // can be managed by this driver. Read the PCI Configuration Header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PciIo->Pci.Read (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint32,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (Pci) / sizeof (UINT32),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Pci
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Pci.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE || Pci.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruDriverBindingStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create handles for IDE channels specified by RemainingDevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install SCSI Pass Thru Protocol onto each created handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller - Handle of device to test
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemainingDevicePath - Not used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PROTOCOL *PciIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Supports;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 OriginalPciAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN PciAttributesSaved;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_DRIVER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciAttributesSaved = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save original PCI attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PciIo->Attributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoAttributeOperationGet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &OriginalPciAttributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciAttributesSaved = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PciIo->Attributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoAttributeOperationSupported,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Supports
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Supports &= (EFI_PCI_DEVICE_ENABLE |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PciIo->Attributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoAttributeOperationEnable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Supports,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Done;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create SCSI Pass Thru instance for the IDE channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = RegisterAtapiScsiPassThru (This, Controller, PciIo, OriginalPciAttributes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDone:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PciAttributesSaved == TRUE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restore original PCI attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo->Attributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoAttributeOperationSet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OriginalPciAttributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruDriverBindingStop (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NumberOfChildren,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE *ChildHandleBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stop this driver on ControllerHandle. Support stoping any child handles
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync created by this driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller - Handle of device to stop driver on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfChildren - Number of Children in the ChildHandleBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandleBuffer - List of handles for the children we need to stop.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdSupportScsiPassThru)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &ScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (ScsiPassThru);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &AtapiScsiPrivate->ScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiExtScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &AtapiScsiPrivate->ExtScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &AtapiScsiPrivate->ScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiExtScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &ExtScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (ExtScsiPassThru);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiExtScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &AtapiScsiPrivate->ExtScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restore original PCI attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo->Attributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoAttributeOperationSet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->OriginalPciAttributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPciIoProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool (AtapiScsiPrivate);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRegisterAtapiScsiPassThru (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 OriginalPciAttributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attaches SCSI Pass Thru Protocol for specified IDE channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller - Parent device handle to the IDE channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - PCI I/O protocol attached on the "Controller".
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (AtapiScsiPrivate == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->Handle = Controller;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will reset the IoPort inside each API function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo = PciIo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->OriginalPciAttributes = OriginalPciAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Obtain IDE IO port registers' base addresses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitAtapiIoPortRegisters(AtapiScsiPrivate, IdeRegsBaseAddr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the LatestTargetId to MAX_TARGET_ID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestTargetId = MAX_TARGET_ID;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestLun = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = InstallScsiPassThruProtocols (&Controller, AtapiScsiPrivate);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruFunction (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This: The EFI_SCSI_PASS_THRU_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target: The Target ID of the ATAPI device to send the SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Request Packet. To ATAPI devices attached on an IDE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Channel, Target ID 0 indicates Master device;Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ID 1 indicates Slave device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun: The LUN of the ATAPI device to send the SCSI Request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet. To the ATAPI device, Lun is always 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet: The SCSI Request Packet to send to the ATAPI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event: If non-blocking I/O is not supported then Event is ignored,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and blocking I/O is performed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Event is NULL, then blocking I/O is performed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Event is not NULL and non blocking I/O is supported,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then non-blocking I/O is performed, and Event will be signaled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync when the SCSI Request Packet completes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target is not allowed beyond MAX_TARGET_ID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check the data fields in Packet parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CheckSCSIRequestPacket (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Request Packet targets at the IDE channel itself,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // do nothing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Target == This->Mode->AdapterId) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->TransferLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // According to Target ID, reset the Atapi I/O Register mapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target Id in [2,3] area, using AtapiIoPortRegisters[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Target / 2) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target = Target % 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target = Target % 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the ATAPI SCSI interface does not support non-blocking I/O
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ignore the Event parameter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Performs blocking I/O.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruGetNextDevice (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT32 *Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT64 *Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to retrieve the list of legal Target IDs for SCSI devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - On input, a pointer to the Target ID of a SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device present on the SCSI channel. On output,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a pointer to the Target ID of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on a SCSI channel. An input value of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xFFFFFFFF retrieves the Target ID of the first
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCSI device present on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - On input, a pointer to the LUN of a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on the SCSI channel. On output, a pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to the LUN of the next SCSI device present on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The Target ID and Lun of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on the SCSI channel was returned in Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned on a previous call to GetNextDevice().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve Device Private Data Structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether Target is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Target == NULL || Lun == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*Target != 0xFFFFFFFF) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((*Target != AtapiScsiPrivate->LatestTargetId) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Lun != AtapiScsiPrivate->LatestLun))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Target == MAX_TARGET_ID) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Target == 0xFFFFFFFF) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Target = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Target = AtapiScsiPrivate->LatestTargetId + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Lun = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the LatestTargetId.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestTargetId = *Target;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestLun = *Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruBuildDevicePath (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to allocate and build a device path node for a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on a SCSI channel. Would not build device path for a SCSI Host Controller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - The Target ID of the SCSI device for which
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a device path node is to be allocated and built.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - The LUN of the SCSI device for which a device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync path node is to be allocated and built.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath - A pointer to a single device path node that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync describes the SCSI device specified by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target and Lun. This function is responsible
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for allocating the buffer DevicePath with the boot
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync service AllocatePool(). It is the caller's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsibility to free DevicePath when the caller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is finished with DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The device path node that describes the SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target and Lun was allocated and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned in DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - The SCSI devices specified by Target and Lun does
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync not exist on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - DevicePath is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OUT_OF_RESOURCES - There are not enough resources to allocate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEV_PATH *Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate parameters passed in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DevicePath == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // can not build device path for the SCSI Host Controller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Target > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Node == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->DevPath.Type = MESSAGING_DEVICE_PATH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->DevPath.SubType = MSG_ATAPI_DP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.PrimarySecondary = (UINT8) (Target / 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.SlaveMaster = (UINT8) (Target % 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.Lun = (UINT16) Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruGetTargetLun (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to translate a device path node to a Target ID and LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath - A pointer to the device path node that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync describes a SCSI device on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - A pointer to the Target ID of a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - A pointer to the LUN of a SCSI device on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - DevicePath was successfully translated to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target ID and LUN, and they were returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - This driver does not support the device path
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync node type in DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - A valid translation from DevicePath to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target ID and LUN does not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEV_PATH *Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate parameters passed in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DevicePath == NULL || Target == NULL || Lun == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DevicePath->SubType != MSG_ATAPI_DP) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node = (EFI_DEV_PATH *) DevicePath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Target = Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Lun = Node->Atapi.Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Target > (MAX_TARGET_ID - 1) || *Lun != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruResetChannel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Resets a SCSI channel.This operation resets all the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCSI devices connected to the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The SCSI channel was reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - The SCSI channel does not support
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a channel reset operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - A device error occurred while
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync attempting to reset the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TIMEOUT - A timeout occurred while attempting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to reset the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 DeviceControlValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN ResetFlag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ResetFlag = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset both Primary channel and Secondary channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so, the IoPort pointer must point to the right I/O Register group
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < 2; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // set SRST bit to initiate soft reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue |= SRST;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // disable Interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue |= BIT1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.DeviceControl,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wait 10us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clear SRST bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 0xfb:1111,1011
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue &= 0xfb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // slave device needs at most 31s to clear BSY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ResetFlag = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ResetFlag) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiScsiPassThruResetTarget (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Resets a SCSI device that is connected to a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - The Target ID of the SCSI device to reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - The LUN of the SCSI device to reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The SCSI device specified by Target and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun was reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - The SCSI channel does not support a target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reset operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Target or Lun are invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - A device error occurred while attempting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to reset the SCSI device specified by Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TIMEOUT - A timeout occurred while attempting to reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the SCSI device specified by Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Command;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 DeviceSelect;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Directly return EFI_SUCCESS if want to reset the host controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Target == This->Mode->AdapterId) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // According to Target ID, reset the Atapi I/O Register mapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target Id in [2,3] area, using AtapiIoPortRegisters[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Target / 2) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATAPI device, no need to wait DRDY ready after device selecting.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // bit7 and bit5 are both set to 1 for backward compatibility
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Target << 4)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Command = ATAPI_SOFT_RESET_CMD;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY clear is the only status return to the host by the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // when reset is complete.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // slave device needs at most 31s to clear BSY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // stall 5 seconds to make the device status stable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (5000000);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruFunction (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This: The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target: The Target ID of the ATAPI device to send the SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Request Packet. To ATAPI devices attached on an IDE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Channel, Target ID 0 indicates Master device;Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ID 1 indicates Slave device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun: The LUN of the ATAPI device to send the SCSI Request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet. To the ATAPI device, Lun is always 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet: The SCSI Request Packet to send to the ATAPI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event: If non-blocking I/O is not supported then Event is ignored,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and blocking I/O is performed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Event is NULL, then blocking I/O is performed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Event is not NULL and non blocking I/O is supported,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then non-blocking I/O is performed, and Event will be signaled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync when the SCSI Request Packet completes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 TargetId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For ATAPI device, UINT8 is enough to represent the SCSI ID on channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = Target[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target is not allowed beyond MAX_TARGET_ID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check the data fields in Packet parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CheckExtSCSIRequestPacket (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Request Packet targets at the IDE channel itself,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // do nothing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TargetId == (UINT8)This->Mode->AdapterId) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength = Packet->OutTransferLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // According to Target ID, reset the Atapi I/O Register mapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target Id in [2,3] area, using AtapiIoPortRegisters[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((TargetId / 2) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = (UINT8) (TargetId % 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = (UINT8) (TargetId % 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the ATAPI SCSI interface does not support non-blocking I/O
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ignore the Event parameter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Performs blocking I/O.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SubmitExtBlockingIoCommand (AtapiScsiPrivate, TargetId, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruGetNextTargetLun (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT8 **Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT64 *Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to retrieve the list of legal Target IDs for SCSI devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - On input, a pointer to the Target ID of a SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device present on the SCSI channel. On output,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a pointer to the Target ID of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on a SCSI channel. An input value of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xFFFFFFFF retrieves the Target ID of the first
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCSI device present on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - On input, a pointer to the LUN of a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on the SCSI channel. On output, a pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to the LUN of the next SCSI device present on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The Target ID and Lun of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on the SCSI channel was returned in Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned on a previous call to GetNextDevice().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ByteIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 TargetId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ScsiId[TARGET_MAX_BYTES];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve Device Private Data Structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether Target is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Target == NULL || Lun == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = (*Target)[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*Target)[ByteIndex] != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((TargetId != AtapiScsiPrivate->LatestTargetId) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Lun != AtapiScsiPrivate->LatestLun))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TargetId == MAX_TARGET_ID) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (*Target, TARGET_MAX_BYTES,0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Lun = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the LatestTargetId.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestTargetId = (*Target)[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestLun = *Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruBuildDevicePath (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to allocate and build a device path node for a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on a SCSI channel. Would not build device path for a SCSI Host Controller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - The Target ID of the SCSI device for which
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a device path node is to be allocated and built.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - The LUN of the SCSI device for which a device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync path node is to be allocated and built.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath - A pointer to a single device path node that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync describes the SCSI device specified by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target and Lun. This function is responsible
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for allocating the buffer DevicePath with the boot
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync service AllocatePool(). It is the caller's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsibility to free DevicePath when the caller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is finished with DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The device path node that describes the SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target and Lun was allocated and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned in DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - The SCSI devices specified by Target and Lun does
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync not exist on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - DevicePath is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OUT_OF_RESOURCES - There are not enough resources to allocate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEV_PATH *Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 TargetId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = Target[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate parameters passed in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DevicePath == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // can not build device path for the SCSI Host Controller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((TargetId > (MAX_TARGET_ID - 1)) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Node == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->DevPath.Type = MESSAGING_DEVICE_PATH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->DevPath.SubType = MSG_ATAPI_DP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.PrimarySecondary = (UINT8) (TargetId / 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.SlaveMaster = (UINT8) (TargetId % 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node->Atapi.Lun = (UINT16) Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruGetTargetLun (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT8 **Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to translate a device path node to a Target ID and LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath - A pointer to the device path node that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync describes a SCSI device on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - A pointer to the Target ID of a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - A pointer to the LUN of a SCSI device on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - DevicePath was successfully translated to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target ID and LUN, and they were returned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - This driver does not support the device path
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync node type in DevicePath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - A valid translation from DevicePath to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target ID and LUN does not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEV_PATH *Node;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate parameters passed in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DevicePath == NULL || Target == NULL || Lun == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DevicePath->SubType != MSG_ATAPI_DP) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (*Target, TARGET_MAX_BYTES);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Node = (EFI_DEV_PATH *) DevicePath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Target)[0] = (UINT8) (Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Lun = Node->Atapi.Lun;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*Target)[0] > (MAX_TARGET_ID - 1) || *Lun != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruResetChannel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Resets a SCSI channel.This operation resets all the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCSI devices connected to the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The SCSI channel was reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - The SCSI channel does not support
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a channel reset operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - A device error occurred while
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync attempting to reset the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TIMEOUT - A timeout occurred while attempting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to reset the SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 DeviceControlValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN ResetFlag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ResetFlag = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset both Primary channel and Secondary channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so, the IoPort pointer must point to the right I/O Register group
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // And if there is a channel reset successfully, return EFI_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < 2; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // set SRST bit to initiate soft reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue |= SRST;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // disable Interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue |= BIT1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.DeviceControl,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wait 10us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clear SRST bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 0xfb:1111,1011
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceControlValue &= 0xfb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // slave device needs at most 31s to clear BSY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ResetFlag = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ResetFlag) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruResetTarget (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Lun
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Resets a SCSI device that is connected to a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - The Target ID of the SCSI device to reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - The LUN of the SCSI device to reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The SCSI device specified by Target and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun was reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - The SCSI channel does not support a target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reset operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Target or Lun are invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - A device error occurred while attempting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to reset the SCSI device specified by Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TIMEOUT - A timeout occurred while attempting to reset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the SCSI device specified by Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Command;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 DeviceSelect;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 TargetId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = Target[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Directly return EFI_SUCCESS if want to reset the host controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TargetId == This->Mode->AdapterId) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // According to Target ID, reset the Atapi I/O Register mapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Target Id in [2,3] area, using AtapiIoPortRegisters[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((TargetId / 2) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATAPI device, no need to wait DRDY ready after device selecting.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // bit7 and bit5 are both set to 1 for backward compatibility
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceSelect = (UINT8) ((BIT7 | BIT5) | (TargetId << 4));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Command = ATAPI_SOFT_RESET_CMD;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY clear is the only status return to the host by the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // when reset is complete.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // slave device needs at most 31s to clear BSY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // stall 5 seconds to make the device status stable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (5000000);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiExtScsiPassThruGetNextTarget (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT8 **Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Used to retrieve the list of legal Target IDs for SCSI devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - On input, a pointer to the Target ID of a SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device present on the SCSI channel. On output,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a pointer to the Target ID of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on a SCSI channel. An input value of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xFFFFFFFF retrieves the Target ID of the first
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SCSI device present on a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lun - On input, a pointer to the LUN of a SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync present on the SCSI channel. On output, a pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to the LUN of the next SCSI device present on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - The Target ID and Lun of the next SCSI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync on the SCSI channel was returned in Target and Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned on a previous call to GetNextDevice().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 TargetId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ScsiId[TARGET_MAX_BYTES];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ByteIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve Device Private Data Structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether Target is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Target == NULL ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetId = (*Target)[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*Target)[ByteIndex] != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&(TargetId != AtapiScsiPrivate->LatestTargetId)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TargetId == MAX_TARGET_ID) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (*Target, TARGET_MAX_BYTES, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the LatestTargetId.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestTargetId = (*Target)[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->LatestLun = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetIdeRegistersBaseAddr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync use fixed addresses. In Native-PCI mode, get base addresses from BARs in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the PCI IDE controller's Configuration Space.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync receive IDE IO port registers' base addresses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PCI_TYPE00 PciData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PciIo->Pci.Read (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint8,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (PciData),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &PciData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The BARs should be of IO type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PciData.Device.Bar[0] & BIT0) == 0 ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PciData.Device.Bar[1] & BIT0) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The BARs should be of IO type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PciData.Device.Bar[2] & BIT0) == 0 ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PciData.Device.Bar[3] & BIT0) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitAtapiIoPortRegisters (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize each Channel's Base Address of CommandBlock and ControlBlock.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync None
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 IdeChannel;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CommandBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 ControlBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_BASE_REGISTERS *RegisterPointer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (IdeChannel = 0; IdeChannel < ATAPI_MAX_CHANNEL; IdeChannel++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer = &AtapiScsiPrivate->AtapiIoPortRegisters[IdeChannel];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize IDE IO port addresses, including Command Block registers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and Control Block registers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->Data = CommandBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &RegisterPointer->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &RegisterPointer->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &RegisterPointer->Alt) = ControlBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegisterPointer->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCheckSCSIRequestPacket (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the parameters in the SCSI Request Packet to make sure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync they are valid for a SCSI Pass Thru request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!ValidCdbLength (Packet->CdbLength)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->Cdb == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Checks whether the request command is supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsCommandValid (Packet)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIsCommandValid (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the requested SCSI command:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Is it supported by this driver?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Is the Data transfer direction reasonable?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *OpCode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ArrayLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OpCode = (UINT8 *) (Packet->Cdb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ArrayLen = (UINT8) (sizeof (gSupportedATAPICommands) / sizeof (gSupportedATAPICommands[0]));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested Command is supported by this driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->DataDirection == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested data direction conforms to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // what it should be.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gSupportedATAPICommands[Index].Direction == DataOut) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->DataDirection == DataOut) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested data direction conforms to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // what it should be.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gSupportedATAPICommands[Index].Direction == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSubmitBlockingIoCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Performs blocking I/O request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate: Private data structure for the specified channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target: The Target ID of the ATAPI device to send the SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Request Packet. To ATAPI devices attached on an IDE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Channel, Target ID 0 indicates Master device;Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ID 1 indicates Slave device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet: The SCSI Request Packet to send to the ATAPI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns: EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 PacketCommand[12];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill ATAPI Command Packet according to CDB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&PacketCommand, 12);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Submit ATAPI Command Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommandStatus = AtapiPacketCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommand,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->DataBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Packet->TransferLength),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (DATA_DIRECTION) Packet->DataDirection,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return SenseData if PacketCommandStatus matches
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the following return codes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PacketCommandStatus == EFI_DEVICE_ERROR) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PacketCommandStatus == EFI_TIMEOUT)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // avoid submit request sense command continuously.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PacketCommand[0] == OP_REQUEST_SENSE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RequestSenseCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->Timeout,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Packet->SenseDataLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRequestSenseCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Timeout,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *SenseData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *SenseDataLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sumbit request sense command
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pionter of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target - The target ID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Timeout - The time to complete the command
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SenseData - The buffer to fill in sense data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SenseDataLength - The length of buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET Packet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Cdb[12];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Packet, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Cdb, 12);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cdb[0] = OP_REQUEST_SENSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cdb[4] = (UINT8) (*SenseDataLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.Timeout = Timeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.DataBuffer = SenseData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.SenseData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.Cdb = Cdb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.TransferLength = *SenseDataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.CdbLength = 12;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet.DataDirection = DataIn;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, &Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *SenseDataLength = (UINT8) (Packet.TransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCheckExtSCSIRequestPacket (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the parameters in the SCSI Request Packet to make sure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync they are valid for a SCSI Pass Thru request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet - The pointer of EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!ValidCdbLength (Packet->CdbLength)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->Cdb == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Checks whether the request command is supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsExtCommandValid (Packet)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIsExtCommandValid (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checks the requested SCSI command:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Is it supported by this driver?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Is the Data transfer direction reasonable?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *OpCode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ArrayLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OpCode = (UINT8 *) (Packet->Cdb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ArrayLen = (UINT8) (sizeof (gSupportedATAPICommands) / sizeof (gSupportedATAPICommands[0]));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*OpCode == gSupportedATAPICommands[Index].OpCode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested Command is supported by this driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->DataDirection == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested data direction conforms to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // what it should be.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gSupportedATAPICommands[Index].Direction == DataOut) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->DataDirection == DataOut) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the requested data direction conforms to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // what it should be.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gSupportedATAPICommands[Index].Direction == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSubmitExtBlockingIoCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Performs blocking I/O request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate: Private data structure for the specified channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target: The Target ID of the ATAPI device to send the SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Request Packet. To ATAPI devices attached on an IDE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Channel, Target ID 0 indicates Master device;Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ID 1 indicates Slave device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet: The SCSI Request Packet to send to the ATAPI device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by Target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns: EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 PacketCommand[12];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill ATAPI Command Packet according to CDB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&PacketCommand, 12);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Timeout is 100ns unit, convert it to 1000ns (1us) unit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Submit ATAPI Command Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->DataDirection == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommandStatus = AtapiPacketCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommand,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InDataBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Packet->InTransferLength),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataIn,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommandStatus = AtapiPacketCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommand,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->OutDataBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(Packet->OutTransferLength),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOut,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return SenseData if PacketCommandStatus matches
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the following return codes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PacketCommandStatus == EFI_DEVICE_ERROR) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (PacketCommandStatus == EFI_TIMEOUT)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // avoid submit request sense command continuously.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PacketCommand[0] == OP_REQUEST_SENSE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseDataLength = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RequestSenseCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->Timeout,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Packet->SenseDataLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PacketCommandStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiPacketCommand (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Target,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *PacketCommand,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *Buffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 *ByteCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DATA_DIRECTION Direction,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Submits ATAPI command packet to the specified ATAPI device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate: Private data structure for the specified channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Target: The Target ID of the ATAPI device to send the SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Request Packet. To ATAPI devices attached on an IDE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Channel, Target ID 0 indicates Master device;Target
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ID 1 indicates Slave device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketCommand: Points to the ATAPI command packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer: Points to the transferred data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ByteCount: When input,indicates the buffer size; when output,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync indicates the actually transferred data size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Direction: Indicates the data transfer direction.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The timeout, in micro second units, to use for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync execution of this ATAPI command.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync A TimeoutInMicroSeconds value of 0 means that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this function will wait indefinitely for the ATAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync command to execute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is greater than zero, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this function will return EFI_TIMEOUT if the time
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required to execute the ATAPI command is greater
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync than TimeoutInMicroSeconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *CommandIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Count;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set all the command parameters by fill related registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Before write to all the following registers, BSY must be 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select device via Device/Head Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // "Target = 0" indicates device 0; "Target = 1" indicates device 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set all the command parameters by fill related registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Before write to all the following registers, BSY DRQ must be 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = StatusDRQClear(AtapiScsiPrivate, TimeoutInMicroSeconds);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_ABORTED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ByteCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No OVL; No DMA (by setting feature register)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Feature,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x00
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // determine how much data should be transfered.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->CylinderLsb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->CylinderMsb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DEFAULT_CTL:0x0a (0000,1010)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Disable interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.DeviceControl,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEFAULT_CTL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send Packet command to inform device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // that the following data bytes are command packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Command,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PACKET_CMD
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Before data transfer, BSY should be 0 and DRQ should be 1.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if they are not in specified time frame,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // retrieve Sense Key from Error Register before return.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_ABORTED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ByteCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send out command packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CommandIndex = (UINT16 *) PacketCommand;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Count = 0; Count < 6; Count++, CommandIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *CommandIndex);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // call AtapiPassThruPioReadWriteData() function to get
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // requested transfer data form device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return AtapiPassThruPioReadWriteData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ByteCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Direction,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiPassThruPioReadWriteData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *Buffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 *ByteCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DATA_DIRECTION Direction,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Performs data transfer between ATAPI device and host after the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI command packet is sent.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate: Private data structure for the specified channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer: Points to the transferred data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ByteCount: When input,indicates the buffer size; when output,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync indicates the actually transferred data size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Direction: Indicates the data transfer direction.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The timeout, in micro second units, to use for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync execution of this ATAPI command.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync A TimeoutInMicroSeconds value of 0 means that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this function will wait indefinitely for the ATAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync command to execute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is greater than zero, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this function will return EFI_TIMEOUT if the time
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required to execute the ATAPI command is greater
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync than TimeoutInMicroSeconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 RequiredWordCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 ActualWordCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 WordCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *ptrBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Non Data transfer request is also supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*ByteCount == 0 || Buffer == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ByteCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ptrBuffer = Buffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RequiredWordCount = *ByteCount / 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ActuralWordCount means the word count of data really transfered.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ActualWordCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (ActualWordCount < RequiredWordCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // before each data transfer stream, the host should poll DRQ bit ready,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // which indicates device's ready for data transfer .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ByteCount = ActualWordCount * 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ActualWordCount == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ActualWordCount > 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ActualWordCount < RequiredWordCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_BAD_BUFFER_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // get current data transfer size from Cylinder Registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordCount = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderMsb) << 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordCount = WordCount | ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderLsb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordCount = WordCount & 0xffff;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WordCount /= 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // perform a series data In/Out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Direction == DataIn) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ptrBuffer = ReadPortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *ptrBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ptrBuffer++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // After data transfer is completed, normally, DRQ bit should clear.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // read status register to check whether error happens.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ByteCount = ActualWordCount * 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT8
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read one byte from a specified I/O port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - The pointer of EFI_PCI_IO_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port - IO port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync A byte read out
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo->Io.Read (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint8,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PASS_THROUGH_BAR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT64) Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReadPortW (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read one word from a specified I/O port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - The pointer of EFI_PCI_IO_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port - IO port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync A word read out
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo->Io.Read (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint16,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PASS_THROUGH_BAR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT64) Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWritePortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Write one byte to a specified I/O port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - The pointer of EFI_PCI_IO_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port - IO port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data - The data to write
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NONE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo->Io.Write (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint8,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PASS_THROUGH_BAR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT64) Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWritePortW (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PCI_IO_PROTOCOL *PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Write one word to a specified I/O port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo - The pointer of EFI_PCI_IO_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Port - IO port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data - The data to write
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NONE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo->Io.Write (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiPciIoWidthUint16,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PCI_IO_PASS_THROUGH_BAR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT64) Port,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncStatusDRQClear (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRQ is clear in the Status Register. (BSY must also be cleared)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 StatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // wait for BSY == 0 and DRQ == 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (DRQ | BSY)) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check whether the command is aborted by the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAltStatusDRQClear (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRQ is clear in the Alternate Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine should
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 AltStatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AltStatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.AltStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // wait for BSY == 0 and DRQ == 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (DRQ | BSY)) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncStatusDRQReady (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRQ is ready in the Status Register. (BSY must also be cleared)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 StatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // read Status Register will clear interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY==0,DRQ==1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (BSY | DRQ)) == DRQ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAltStatusDRQReady (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRQ is ready in the Alternate Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BSY must also be cleared)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 AltStatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // read Status Register will clear interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AltStatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.AltStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY==0,DRQ==1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (BSY | DRQ)) == DRQ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncStatusWaitForBSYClear (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether BSY is clear in the Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 StatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & BSY) == 0x00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAltStatusWaitForBSYClear (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether BSY is clear in the Alternate Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 AltStatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AltStatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.AltStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & BSY) == 0x00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncStatusDRDYReady (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRDY is ready in the Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BSY must also be cleared)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 StatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY == 0 , DRDY == 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (DRDY | BSY)) == DRDY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAltStatusDRDYReady (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TimeoutInMicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether DRDY is ready in the Alternate Status Register.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BSY must also be cleared)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elapsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutInMicroSeconds - The time to wait for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 AltStatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AltStatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Alt.AltStatus
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BSY == 0 , DRDY == 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (DRDY | BSY)) == DRDY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((AltStatusRegister & (BSY | ERR)) == ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg1.Error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stall for 30 us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (30);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop infinitely if not meeting expected condition
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutInMicroSeconds == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Delay);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Delay == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAtapiPassThruCheckErrorStatus (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check Error Register for Error Information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncArguments:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncReturns:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 StatusRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 ErrorRegister;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister = ReadPortB (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->PciIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AtapiScsiPrivate->IoPort->Reg.Status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_BEGIN ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StatusRegister & DWF) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StatusRegister & CORR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StatusRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StatusRegister & ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & BBK_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & UNC_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & MC_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & ABRT_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & TK0NF_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorRegister & AMNF_ERR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_D_BLKIO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorRegister)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG_CODE_END ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((StatusRegister & (ERR | DWF | CORR)) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Installs Scsi Pass Thru and/or Ext Scsi Pass Thru
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync protocols based on feature flags.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Controller The controller handle to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync install these protocols on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param AtapiScsiPrivate A pointer to the protocol private
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The installation succeeds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other The installation fails.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInstallScsiPassThruProtocols (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE *ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiPassThru = &AtapiScsiPrivate->ScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtScsiPassThru = &AtapiScsiPrivate->ExtScsiPassThru;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdSupportScsiPassThru)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiPassThru = CopyMem (ScsiPassThru, &gScsiPassThruProtocolTemplate, sizeof (*ScsiPassThru));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiExtScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiExtScsiPassThruProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtScsiPassThru,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This driver must support either ScsiPassThru or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ExtScsiPassThru protocols
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The user Entry Point for module AtapiPassThru. The user code starts with this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the EFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The entry point is executed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Some error occurs when executing this entry point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitializeAtapiPassThru(
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_TABLE *SystemTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install driver model protocol(s).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibInstallDriverBindingComponentName2 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gAtapiScsiPassThruDriverBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gAtapiScsiPassThruComponentName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gAtapiScsiPassThruComponentName2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install EFI Driver Supported EFI Version Protocol required for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // EFI drivers that are on PCI and other plug in cards.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gAtapiScsiPassThruDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiDriverSupportedEfiVersionProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gAtapiScsiPassThruDriverSupportedEfiVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}