--- /dev/null
+/** @file\r
+ Copyright (c) 2006, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ Module Name: AtapiPassThru.h\r
+\r
+**/\r
+\r
+#ifndef _APT_H\r
+#define _APT_H\r
+\r
+\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/ScsiPassThru.h>\r
+#include <Protocol/ScsiPassThruExt.h>\r
+#include <Protocol/PciIo.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <IndustryStandard/pci22.h>\r
+\r
+///\r
+/// bit definition\r
+///\r
+#define bit(a) (1 << (a))\r
+\r
+#define MAX_TARGET_ID 4\r
+\r
+//\r
+// IDE Registers\r
+//\r
+typedef union {\r
+ UINT16 Command; /* when write */\r
+ UINT16 Status; /* when read */\r
+} IDE_CMD_OR_STATUS;\r
+\r
+typedef union {\r
+ UINT16 Error; /* when read */\r
+ UINT16 Feature; /* when write */\r
+} IDE_ERROR_OR_FEATURE;\r
+\r
+typedef union {\r
+ UINT16 AltStatus; /* when read */\r
+ UINT16 DeviceControl; /* when write */\r
+} IDE_AltStatus_OR_DeviceControl;\r
+\r
+\r
+typedef enum {\r
+ IdePrimary = 0,\r
+ IdeSecondary = 1,\r
+ IdeMaxChannel = 2\r
+} EFI_IDE_CHANNEL;\r
+\r
+///\r
+\r
+\r
+//\r
+// Bit definitions in Programming Interface byte of the Class Code field\r
+// in PCI IDE controller's Configuration Space\r
+//\r
+#define IDE_PRIMARY_OPERATING_MODE BIT0\r
+#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1\r
+#define IDE_SECONDARY_OPERATING_MODE BIT2\r
+#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3\r
+\r
+\r
+#define ATAPI_MAX_CHANNEL 2\r
+\r
+///\r
+/// IDE registers set\r
+///\r
+typedef struct {\r
+ UINT16 Data;\r
+ IDE_ERROR_OR_FEATURE Reg1;\r
+ UINT16 SectorCount;\r
+ UINT16 SectorNumber;\r
+ UINT16 CylinderLsb;\r
+ UINT16 CylinderMsb;\r
+ UINT16 Head;\r
+ IDE_CMD_OR_STATUS Reg;\r
+ IDE_AltStatus_OR_DeviceControl Alt;\r
+ UINT16 DriveAddress;\r
+} IDE_BASE_REGISTERS;\r
+\r
+#define ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE EFI_SIGNATURE_32 ('a', 's', 'p', 't')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE Handle;\r
+ EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru;\r
+ EFI_EXT_SCSI_PASS_THRU_PROTOCOL ExtScsiPassThru;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT64 OriginalPciAttributes;\r
+ //\r
+ // Local Data goes here\r
+ //\r
+ IDE_BASE_REGISTERS *IoPort;\r
+ IDE_BASE_REGISTERS AtapiIoPortRegisters[2];\r
+ UINT32 LatestTargetId;\r
+ UINT64 LatestLun;\r
+} ATAPI_SCSI_PASS_THRU_DEV;\r
+\r
+//\r
+// IDE registers' base addresses\r
+//\r
+typedef struct {\r
+ UINT16 CommandBlockBaseAddr;\r
+ UINT16 ControlBlockBaseAddr;\r
+} IDE_REGISTERS_BASE_ADDR;\r
+\r
+#define ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS(a) \\r
+ CR (a, \\r
+ ATAPI_SCSI_PASS_THRU_DEV, \\r
+ ScsiPassThru, \\r
+ ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \\r
+ )\r
+\r
+#define ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS(a) \\r
+ CR (a, \\r
+ ATAPI_SCSI_PASS_THRU_DEV, \\r
+ ExtScsiPassThru, \\r
+ ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE \\r
+ )\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gAtapiScsiPassThruComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gAtapiScsiPassThruComponentName2;\r
+\r
+//\r
+// ATAPI Command op code\r
+//\r
+#define OP_INQUIRY 0x12\r
+#define OP_LOAD_UNLOAD_CD 0xa6\r
+#define OP_MECHANISM_STATUS 0xbd\r
+#define OP_MODE_SELECT_10 0x55\r
+#define OP_MODE_SENSE_10 0x5a\r
+#define OP_PAUSE_RESUME 0x4b\r
+#define OP_PLAY_AUDIO_10 0x45\r
+#define OP_PLAY_AUDIO_MSF 0x47\r
+#define OP_PLAY_CD 0xbc\r
+#define OP_PLAY_CD_MSF 0xb4\r
+#define OP_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e\r
+#define OP_READ_10 0x28\r
+#define OP_READ_12 0xa8\r
+#define OP_READ_CAPACITY 0x25\r
+#define OP_READ_CD 0xbe\r
+#define OP_READ_CD_MSF 0xb9\r
+#define OP_READ_HEADER 0x44\r
+#define OP_READ_SUB_CHANNEL 0x42\r
+#define OP_READ_TOC 0x43\r
+#define OP_REQUEST_SENSE 0x03\r
+#define OP_SCAN 0xba\r
+#define OP_SEEK_10 0x2b\r
+#define OP_SET_CD_SPEED 0xbb\r
+#define OP_STOPPLAY_SCAN 0x4e\r
+#define OP_START_STOP_UNIT 0x1b\r
+#define OP_TEST_UNIT_READY 0x00\r
+\r
+#define OP_FORMAT_UNIT 0x04\r
+#define OP_READ_FORMAT_CAPACITIES 0x23\r
+#define OP_VERIFY 0x2f\r
+#define OP_WRITE_10 0x2a\r
+#define OP_WRITE_12 0xaa\r
+#define OP_WRITE_AND_VERIFY 0x2e\r
+\r
+//\r
+// ATA Command\r
+//\r
+#define ATAPI_SOFT_RESET_CMD 0x08\r
+\r
+typedef enum {\r
+ DataIn = 0,\r
+ DataOut = 1,\r
+ DataBi = 2,\r
+ NoData = 3,\r
+ End = 0xff\r
+} DATA_DIRECTION;\r
+\r
+typedef struct {\r
+ UINT8 OpCode;\r
+ DATA_DIRECTION Direction;\r
+} SCSI_COMMAND_SET;\r
+\r
+#define MAX_CHANNEL 2\r
+\r
+#define ValidCdbLength(Len) ((Len) == 6 || (Len) == 10 || (Len) == 12) ? 1 : 0\r
+\r
+//\r
+// IDE registers bit definitions\r
+//\r
+// ATA Err Reg bitmap\r
+//\r
+#define BBK_ERR bit (7) ///< Bad block detected\r
+#define UNC_ERR bit (6) ///< Uncorrectable Data\r
+#define MC_ERR bit (5) ///< Media Change\r
+#define IDNF_ERR bit (4) ///< ID Not Found\r
+#define MCR_ERR bit (3) ///< Media Change Requested\r
+#define ABRT_ERR bit (2) ///< Aborted Command\r
+#define TK0NF_ERR bit (1) ///< Track 0 Not Found\r
+#define AMNF_ERR bit (0) ///< Address Mark Not Found\r
+\r
+//\r
+// ATAPI Err Reg bitmap\r
+//\r
+#define SENSE_KEY_ERR (bit (7) | bit (6) | bit (5) | bit (4))\r
+#define EOM_ERR bit (1) ///< End of Media Detected\r
+#define ILI_ERR bit (0) ///< Illegal Length Indication\r
+\r
+//\r
+// Device/Head Reg\r
+//\r
+#define LBA_MODE bit (6)\r
+#define DEV bit (4)\r
+#define HS3 bit (3)\r
+#define HS2 bit (2)\r
+#define HS1 bit (1)\r
+#define HS0 bit (0)\r
+#define CHS_MODE (0)\r
+#define DRV0 (0)\r
+#define DRV1 (1)\r
+#define MST_DRV DRV0\r
+#define SLV_DRV DRV1\r
+\r
+//\r
+// Status Reg\r
+//\r
+#define BSY bit (7) ///< Controller Busy\r
+#define DRDY bit (6) ///< Drive Ready\r
+#define DWF bit (5) ///< Drive Write Fault\r
+#define DSC bit (4) ///< Disk Seek Complete\r
+#define DRQ bit (3) ///< Data Request\r
+#define CORR bit (2) ///< Corrected Data\r
+#define IDX bit (1) ///< Index\r
+#define ERR bit (0) ///< Error\r
+#define CHECK bit (0) ///< Check bit for ATAPI Status Reg\r
+\r
+//\r
+// Device Control Reg\r
+//\r
+#define SRST bit (2) ///< Software Reset\r
+#define IEN_L bit (1) ///< Interrupt Enable\r
+\r
+//\r
+// ATAPI Feature Register\r
+//\r
+#define OVERLAP bit (1)\r
+#define DMA bit (0)\r
+\r
+//\r
+// ATAPI Interrupt Reason Reson Reg (ATA Sector Count Register)\r
+//\r
+#define RELEASE bit (2)\r
+#define IO bit (1)\r
+#define CoD bit (0)\r
+\r
+#define PACKET_CMD 0xA0\r
+\r
+#define DEFAULT_CMD (0xa0)\r
+//\r
+// default content of device control register, disable INT\r
+//\r
+#define DEFAULT_CTL (0x0a)\r
+#define MAX_ATAPI_BYTE_COUNT (0xfffe)\r
+\r
+//\r
+// function prototype\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ );\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+ This function retrieves the user readable name of a driver in the form of a\r
+ Unicode string. If the driver specified by This has a user readable name in\r
+ the language specified by Language, then a pointer to the driver name is\r
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+ by This does not support the language specified by Language,\r
+ then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified\r
+ in RFC 3066 or ISO 639-2 language code format.\r
+\r
+ @param DriverName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ driver specified by This in the language\r
+ specified by Language.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by\r
+ This and the language specified by Language was\r
+ returned in DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+\r
+/**\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by a driver.\r
+\r
+ This function retrieves the user readable name of the controller specified by\r
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+ driver specified by This has a user readable name in the language specified by\r
+ Language, then a pointer to the controller name is returned in ControllerName,\r
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently\r
+ managing the controller specified by ControllerHandle and ChildHandle,\r
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not\r
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+ EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+ @param ControllerHandle[in] The handle of a controller that the driver\r
+ specified by This is managing. This handle\r
+ specifies the controller whose name is to be\r
+ returned.\r
+\r
+ @param ChildHandle[in] The handle of the child controller to retrieve\r
+ the name of. This is an optional parameter that\r
+ may be NULL. It will be NULL for device\r
+ drivers. It will also be NULL for a bus drivers\r
+ that wish to retrieve the name of the bus\r
+ controller. It will not be NULL for a bus\r
+ driver that wishes to retrieve the name of a\r
+ child controller.\r
+\r
+ @param Language[in] A pointer to a Null-terminated ASCII string\r
+ array indicating the language. This is the\r
+ language of the driver name that the caller is\r
+ requesting, and it must match one of the\r
+ languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up\r
+ to the driver writer. Language is specified in\r
+ RFC 3066 or ISO 639-2 language code format.\r
+\r
+ @param ControllerName[out] A pointer to the Unicode string to return.\r
+ This Unicode string is the name of the\r
+ controller specified by ControllerHandle and\r
+ ChildHandle in the language specified by\r
+ Language from the point of view of the driver\r
+ specified by This.\r
+\r
+ @retval EFI_SUCCESS The Unicode string for the user readable name in\r
+ the language specified by Language for the\r
+ driver specified by This was returned in\r
+ DriverName.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+\r
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+ EFI_HANDLE.\r
+\r
+ @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently\r
+ managing the controller specified by\r
+ ControllerHandle and ChildHandle.\r
+\r
+ @retval EFI_UNSUPPORTED The driver specified by This does not support\r
+ the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+ /*++\r
+\r
+Routine Description:\r
+\r
+ Entry point for EFI drivers.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - EFI_HANDLE\r
+ SystemTable - EFI_SYSTEM_TABLE\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+ Others \r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RegisterAtapiScsiPassThru (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT64 OriginalPciAttributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Attaches SCSI Pass Thru Protocol for specified IDE channel.\r
+ \r
+Arguments:\r
+ This - Protocol instance pointer.\r
+ Controller - Parent device handle to the IDE channel. \r
+ PciIo - PCI I/O protocol attached on the "Controller". \r
+ \r
+Returns:\r
+ Always return EFI_SUCCESS unless installing SCSI Pass Thru Protocol failed.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruFunction (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT32 Target,\r
+ IN UINT64 Lun,\r
+ IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,\r
+ IN EFI_EVENT Event OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Implements EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() function.\r
+\r
+Arguments:\r
+\r
+ This: The EFI_SCSI_PASS_THRU_PROTOCOL instance.\r
+ Target: The Target ID of the ATAPI device to send the SCSI \r
+ Request Packet. To ATAPI devices attached on an IDE\r
+ Channel, Target ID 0 indicates Master device;Target\r
+ ID 1 indicates Slave device.\r
+ Lun: The LUN of the ATAPI device to send the SCSI Request\r
+ Packet. To the ATAPI device, Lun is always 0.\r
+ Packet: The SCSI Request Packet to send to the ATAPI device \r
+ specified by Target and Lun.\r
+ Event: If non-blocking I/O is not supported then Event is ignored, \r
+ and blocking I/O is performed.\r
+ If Event is NULL, then blocking I/O is performed.\r
+ If Event is not NULL and non blocking I/O is supported, \r
+ then non-blocking I/O is performed, and Event will be signaled \r
+ when the SCSI Request Packet completes. \r
+\r
+Returns: \r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruGetNextDevice (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN OUT UINT32 *Target,\r
+ IN OUT UINT64 *Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to retrieve the list of legal Target IDs for SCSI devices \r
+ on a SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - On input, a pointer to the Target ID of a SCSI \r
+ device present on the SCSI channel. On output, \r
+ a pointer to the Target ID of the next SCSI device\r
+ present on a SCSI channel. An input value of \r
+ 0xFFFFFFFF retrieves the Target ID of the first \r
+ SCSI device present on a SCSI channel.\r
+ Lun - On input, a pointer to the LUN of a SCSI device\r
+ present on the SCSI channel. On output, a pointer\r
+ to the LUN of the next SCSI device present on \r
+ a SCSI channel.\r
+Returns:\r
+\r
+ EFI_SUCCESS - The Target ID and Lun of the next SCSI device \r
+ on the SCSI channel was returned in Target and Lun.\r
+ EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.\r
+ EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not\r
+ returned on a previous call to GetNextDevice().\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruBuildDevicePath (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT32 Target,\r
+ IN UINT64 Lun,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to allocate and build a device path node for a SCSI device \r
+ on a SCSI channel. Would not build device path for a SCSI Host Controller.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - The Target ID of the SCSI device for which\r
+ a device path node is to be allocated and built.\r
+ Lun - The LUN of the SCSI device for which a device \r
+ path node is to be allocated and built.\r
+ DevicePath - A pointer to a single device path node that \r
+ describes the SCSI device specified by \r
+ Target and Lun. This function is responsible \r
+ for allocating the buffer DevicePath with the boot\r
+ service AllocatePool(). It is the caller's \r
+ responsibility to free DevicePath when the caller\r
+ is finished with DevicePath. \r
+ Returns:\r
+ EFI_SUCCESS - The device path node that describes the SCSI device\r
+ specified by Target and Lun was allocated and \r
+ returned in DevicePath.\r
+ EFI_NOT_FOUND - The SCSI devices specified by Target and Lun does\r
+ not exist on the SCSI channel.\r
+ EFI_INVALID_PARAMETER - DevicePath is NULL.\r
+ EFI_OUT_OF_RESOURCES - There are not enough resources to allocate \r
+ DevicePath.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruGetTargetLun (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ OUT UINT32 *Target,\r
+ OUT UINT64 *Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to translate a device path node to a Target ID and LUN.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ DevicePath - A pointer to the device path node that \r
+ describes a SCSI device on the SCSI channel.\r
+ Target - A pointer to the Target ID of a SCSI device \r
+ on the SCSI channel. \r
+ Lun - A pointer to the LUN of a SCSI device on \r
+ the SCSI channel. \r
+Returns:\r
+\r
+ EFI_SUCCESS - DevicePath was successfully translated to a \r
+ Target ID and LUN, and they were returned \r
+ in Target and Lun.\r
+ EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.\r
+ EFI_UNSUPPORTED - This driver does not support the device path \r
+ node type in DevicePath.\r
+ EFI_NOT_FOUND - A valid translation from DevicePath to a \r
+ Target ID and LUN does not exist.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruResetChannel (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Resets a SCSI channel.This operation resets all the \r
+ SCSI devices connected to the SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The SCSI channel was reset.\r
+ EFI_UNSUPPORTED - The SCSI channel does not support \r
+ a channel reset operation.\r
+ EFI_DEVICE_ERROR - A device error occurred while \r
+ attempting to reset the SCSI channel.\r
+ EFI_TIMEOUT - A timeout occurred while attempting \r
+ to reset the SCSI channel.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiScsiPassThruResetTarget (\r
+ IN EFI_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT32 Target,\r
+ IN UINT64 Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Resets a SCSI device that is connected to a SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - The Target ID of the SCSI device to reset. \r
+ Lun - The LUN of the SCSI device to reset.\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS - The SCSI device specified by Target and \r
+ Lun was reset.\r
+ EFI_UNSUPPORTED - The SCSI channel does not support a target\r
+ reset operation.\r
+ EFI_INVALID_PARAMETER - Target or Lun are invalid.\r
+ EFI_DEVICE_ERROR - A device error occurred while attempting \r
+ to reset the SCSI device specified by Target \r
+ and Lun.\r
+ EFI_TIMEOUT - A timeout occurred while attempting to reset \r
+ the SCSI device specified by Target and Lun.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruFunction (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT8 *Target,\r
+ IN UINT64 Lun,\r
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,\r
+ IN EFI_EVENT Event OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Implements EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() function.\r
+\r
+Arguments:\r
+\r
+ This: The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.\r
+ Target: The Target ID of the ATAPI device to send the SCSI \r
+ Request Packet. To ATAPI devices attached on an IDE\r
+ Channel, Target ID 0 indicates Master device;Target\r
+ ID 1 indicates Slave device.\r
+ Lun: The LUN of the ATAPI device to send the SCSI Request\r
+ Packet. To the ATAPI device, Lun is always 0.\r
+ Packet: The SCSI Request Packet to send to the ATAPI device \r
+ specified by Target and Lun.\r
+ Event: If non-blocking I/O is not supported then Event is ignored, \r
+ and blocking I/O is performed.\r
+ If Event is NULL, then blocking I/O is performed.\r
+ If Event is not NULL and non blocking I/O is supported, \r
+ then non-blocking I/O is performed, and Event will be signaled \r
+ when the SCSI Request Packet completes. \r
+\r
+Returns: \r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruGetNextTargetLun (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN OUT UINT8 **Target,\r
+ IN OUT UINT64 *Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to retrieve the list of legal Target IDs for SCSI devices \r
+ on a SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - On input, a pointer to the Target ID of a SCSI \r
+ device present on the SCSI channel. On output, \r
+ a pointer to the Target ID of the next SCSI device\r
+ present on a SCSI channel. An input value of \r
+ 0xFFFFFFFF retrieves the Target ID of the first \r
+ SCSI device present on a SCSI channel.\r
+ Lun - On input, a pointer to the LUN of a SCSI device\r
+ present on the SCSI channel. On output, a pointer\r
+ to the LUN of the next SCSI device present on \r
+ a SCSI channel.\r
+Returns:\r
+\r
+ EFI_SUCCESS - The Target ID and Lun of the next SCSI device \r
+ on the SCSI channel was returned in Target and Lun.\r
+ EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.\r
+ EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not\r
+ returned on a previous call to GetNextDevice().\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruBuildDevicePath (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT8 *Target,\r
+ IN UINT64 Lun,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to allocate and build a device path node for a SCSI device \r
+ on a SCSI channel. Would not build device path for a SCSI Host Controller.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - The Target ID of the SCSI device for which\r
+ a device path node is to be allocated and built.\r
+ Lun - The LUN of the SCSI device for which a device \r
+ path node is to be allocated and built.\r
+ DevicePath - A pointer to a single device path node that \r
+ describes the SCSI device specified by \r
+ Target and Lun. This function is responsible \r
+ for allocating the buffer DevicePath with the boot\r
+ service AllocatePool(). It is the caller's \r
+ responsibility to free DevicePath when the caller\r
+ is finished with DevicePath. \r
+ Returns:\r
+ EFI_SUCCESS - The device path node that describes the SCSI device\r
+ specified by Target and Lun was allocated and \r
+ returned in DevicePath.\r
+ EFI_NOT_FOUND - The SCSI devices specified by Target and Lun does\r
+ not exist on the SCSI channel.\r
+ EFI_INVALID_PARAMETER - DevicePath is NULL.\r
+ EFI_OUT_OF_RESOURCES - There are not enough resources to allocate \r
+ DevicePath.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruGetTargetLun (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ OUT UINT8 **Target,\r
+ OUT UINT64 *Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Used to translate a device path node to a Target ID and LUN.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ DevicePath - A pointer to the device path node that \r
+ describes a SCSI device on the SCSI channel.\r
+ Target - A pointer to the Target ID of a SCSI device \r
+ on the SCSI channel. \r
+ Lun - A pointer to the LUN of a SCSI device on \r
+ the SCSI channel. \r
+Returns:\r
+\r
+ EFI_SUCCESS - DevicePath was successfully translated to a \r
+ Target ID and LUN, and they were returned \r
+ in Target and Lun.\r
+ EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.\r
+ EFI_UNSUPPORTED - This driver does not support the device path \r
+ node type in DevicePath.\r
+ EFI_NOT_FOUND - A valid translation from DevicePath to a \r
+ Target ID and LUN does not exist.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruResetChannel (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Resets a SCSI channel.This operation resets all the \r
+ SCSI devices connected to the SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The SCSI channel was reset.\r
+ EFI_UNSUPPORTED - The SCSI channel does not support \r
+ a channel reset operation.\r
+ EFI_DEVICE_ERROR - A device error occurred while \r
+ attempting to reset the SCSI channel.\r
+ EFI_TIMEOUT - A timeout occurred while attempting \r
+ to reset the SCSI channel.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruResetTarget (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN UINT8 *Target,\r
+ IN UINT64 Lun\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Resets a SCSI device that is connected to a SCSI channel.\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Target - The Target ID of the SCSI device to reset. \r
+ Lun - The LUN of the SCSI device to reset.\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS - The SCSI device specified by Target and \r
+ Lun was reset.\r
+ EFI_UNSUPPORTED - The SCSI channel does not support a target\r
+ reset operation.\r
+ EFI_INVALID_PARAMETER - Target or Lun are invalid.\r
+ EFI_DEVICE_ERROR - A device error occurred while attempting \r
+ to reset the SCSI device specified by Target \r
+ and Lun.\r
+ EFI_TIMEOUT - A timeout occurred while attempting to reset \r
+ the SCSI device specified by Target and Lun.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AtapiExtScsiPassThruGetNextTarget (\r
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
+ IN OUT UINT8 **Target\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Used to retrieve the list of legal Target IDs for SCSI devices \r
+ on a SCSI channel.\r
+\r
+Arguments:\r
+ This - Protocol instance pointer.\r
+ Target - On input, a pointer to the Target ID of a SCSI \r
+ device present on the SCSI channel. On output, \r
+ a pointer to the Target ID of the next SCSI device\r
+ present on a SCSI channel. An input value of \r
+ 0xFFFFFFFF retrieves the Target ID of the first \r
+ SCSI device present on a SCSI channel.\r
+ Lun - On input, a pointer to the LUN of a SCSI device\r
+ present on the SCSI channel. On output, a pointer\r
+ to the LUN of the next SCSI device present on \r
+ a SCSI channel.\r
+ \r
+Returns:\r
+ EFI_SUCCESS - The Target ID and Lun of the next SCSI device \r
+ on the SCSI channel was returned in Target and Lun.\r
+ EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.\r
+ EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not\r
+ returned on a previous call to GetNextDevice().\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CheckSCSIRequestPacket (\r
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Checks the parameters in the SCSI Request Packet to make sure\r
+ they are valid for a SCSI Pass Thru request.\r
+\r
+Arguments:\r
+\r
+ Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET \r
+\r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SubmitBlockingIoCommand (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT32 Target,\r
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs blocking I/O request.\r
+ \r
+Arguments:\r
+\r
+ AtapiScsiPrivate: Private data structure for the specified channel.\r
+ Target: The Target ID of the ATAPI device to send the SCSI \r
+ Request Packet. To ATAPI devices attached on an IDE\r
+ Channel, Target ID 0 indicates Master device;Target\r
+ ID 1 indicates Slave device.\r
+ Packet: The SCSI Request Packet to send to the ATAPI device \r
+ specified by Target.\r
+ \r
+ Returns: EFI_STATUS \r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsCommandValid (\r
+ EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+ /*++\r
+\r
+Routine Description:\r
+\r
+ Checks the requested SCSI command: \r
+ Is it supported by this driver?\r
+ Is the Data transfer direction reasonable?\r
+\r
+Arguments:\r
+\r
+ Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET \r
+\r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CheckExtSCSIRequestPacket (\r
+ EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Checks the parameters in the SCSI Request Packet to make sure\r
+ they are valid for a SCSI Pass Thru request.\r
+\r
+Arguments:\r
+\r
+ Packet - The pointer of EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+ \r
+Returns:\r
+ \r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+\r
+BOOLEAN\r
+IsExtCommandValid (\r
+ EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+ \r
+Routine Description:\r
+\r
+ Checks the requested SCSI command: \r
+ Is it supported by this driver?\r
+ Is the Data transfer direction reasonable?\r
+\r
+Arguments:\r
+\r
+ Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET \r
+\r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SubmitExtBlockingIoCommand (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT8 Target,\r
+ EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs blocking I/O request.\r
+ \r
+Arguments:\r
+\r
+ AtapiScsiPrivate: Private data structure for the specified channel.\r
+ Target: The Target ID of the ATAPI device to send the SCSI \r
+ Request Packet. To ATAPI devices attached on an IDE\r
+ Channel, Target ID 0 indicates Master device;Target\r
+ ID 1 indicates Slave device.\r
+ Packet: The SCSI Request Packet to send to the ATAPI device \r
+ specified by Target.\r
+ \r
+ Returns: EFI_STATUS \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RequestSenseCommand (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT32 Target,\r
+ UINT64 Timeout,\r
+ VOID *SenseData,\r
+ UINT8 *SenseDataLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Sumbit request sense command\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pionter of ATAPI_SCSI_PASS_THRU_DEV\r
+ Target - The target ID\r
+ Timeout - The time to complete the command\r
+ SenseData - The buffer to fill in sense data\r
+ SenseDataLength - The length of buffer\r
+\r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AtapiPacketCommand (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT32 Target,\r
+ UINT8 *PacketCommand,\r
+ VOID *Buffer,\r
+ UINT32 *ByteCount,\r
+ DATA_DIRECTION Direction,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Submits ATAPI command packet to the specified ATAPI device.\r
+ \r
+Arguments:\r
+\r
+ AtapiScsiPrivate: Private data structure for the specified channel.\r
+ Target: The Target ID of the ATAPI device to send the SCSI \r
+ Request Packet. To ATAPI devices attached on an IDE\r
+ Channel, Target ID 0 indicates Master device;Target\r
+ ID 1 indicates Slave device.\r
+ PacketCommand: Points to the ATAPI command packet.\r
+ Buffer: Points to the transferred data.\r
+ ByteCount: When input,indicates the buffer size; when output,\r
+ indicates the actually transferred data size.\r
+ Direction: Indicates the data transfer direction. \r
+ TimeoutInMicroSeconds:\r
+ The timeout, in micro second units, to use for the \r
+ execution of this ATAPI command.\r
+ A TimeoutInMicroSeconds value of 0 means that \r
+ this function will wait indefinitely for the ATAPI \r
+ command to execute.\r
+ If TimeoutInMicroSeconds is greater than zero, then \r
+ this function will return EFI_TIMEOUT if the time \r
+ required to execute the ATAPI command is greater \r
+ than TimeoutInMicroSeconds.\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+\r
+UINT8\r
+ReadPortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read one byte from a specified I/O port.\r
+\r
+Arguments:\r
+\r
+ PciIo - The pointer of EFI_PCI_IO_PROTOCOL\r
+ Port - IO port\r
+ \r
+Returns:\r
+\r
+ A byte read out\r
+\r
+--*/\r
+;\r
+\r
+\r
+UINT16\r
+ReadPortW (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read one word from a specified I/O port.\r
+\r
+Arguments:\r
+\r
+ PciIo - The pointer of EFI_PCI_IO_PROTOCOL\r
+ Port - IO port\r
+ \r
+Returns: \r
+\r
+ A word read out\r
+\r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+WritePortB (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT8 Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write one byte to a specified I/O port.\r
+\r
+Arguments:\r
+\r
+ PciIo - The pointer of EFI_PCI_IO_PROTOCOL\r
+ Port - IO port\r
+ Data - The data to write\r
+ \r
+Returns:\r
+ \r
+ NONE\r
+ \r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+WritePortW (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT16 Port,\r
+ IN UINT16 Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write one word to a specified I/O port.\r
+\r
+Arguments:\r
+\r
+ PciIo - The pointer of EFI_PCI_IO_PROTOCOL\r
+ Port - IO port\r
+ Data - The data to write\r
+ \r
+Returns:\r
+\r
+ NONE\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StatusDRQClear (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRQ is clear in the Status Register. (BSY must also be cleared)\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AltStatusDRQClear (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRQ is clear in the Alternate Status Register. \r
+ (BSY must also be cleared).If TimeoutInMicroSeconds is zero, this routine should \r
+ wait infinitely for DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StatusDRQReady (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRQ is ready in the Status Register. (BSY must also be cleared)\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AltStatusDRQReady (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRQ is ready in the Alternate Status Register. \r
+ (BSY must also be cleared)\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StatusWaitForBSYClear (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether BSY is clear in the Status Register.\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AltStatusWaitForBSYClear (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether BSY is clear in the Alternate Status Register.\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StatusDRDYReady (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRDY is ready in the Status Register. \r
+ (BSY must also be cleared)\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AltStatusDRDYReady (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT64 TimeoutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether DRDY is ready in the Alternate Status Register. \r
+ (BSY must also be cleared)\r
+ If TimeoutInMicroSeconds is zero, this routine should wait infinitely for\r
+ DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is \r
+ elapsed.\r
+\r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ TimeoutInMicroSeconds - The time to wait for\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AtapiPassThruPioReadWriteData (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ UINT16 *Buffer,\r
+ UINT32 *ByteCount,\r
+ DATA_DIRECTION Direction,\r
+ UINT64 TimeOutInMicroSeconds\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs data transfer between ATAPI device and host after the\r
+ ATAPI command packet is sent.\r
+ \r
+Arguments:\r
+\r
+ AtapiScsiPrivate: Private data structure for the specified channel. \r
+ Buffer: Points to the transferred data.\r
+ ByteCount: When input,indicates the buffer size; when output,\r
+ indicates the actually transferred data size.\r
+ Direction: Indicates the data transfer direction. \r
+ TimeoutInMicroSeconds:\r
+ The timeout, in micro second units, to use for the \r
+ execution of this ATAPI command.\r
+ A TimeoutInMicroSeconds value of 0 means that \r
+ this function will wait indefinitely for the ATAPI \r
+ command to execute.\r
+ If TimeoutInMicroSeconds is greater than zero, then \r
+ this function will return EFI_TIMEOUT if the time \r
+ required to execute the ATAPI command is greater \r
+ than TimeoutInMicroSeconds.\r
+ Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AtapiPassThruCheckErrorStatus (\r
+ ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check Error Register for Error Information. \r
+ \r
+Arguments:\r
+\r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+GetIdeRegistersBaseAddr (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,\r
+ use fixed addresses. In Native-PCI mode, get base addresses from BARs in\r
+ the PCI IDE controller's Configuration Space.\r
+\r
+Arguments:\r
+ PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance\r
+ IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to \r
+ receive IDE IO port registers' base addresses\r
+ \r
+Returns:\r
+\r
+ EFI_STATUS\r
+ \r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+InitAtapiIoPortRegisters (\r
+ IN ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,\r
+ IN IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize each Channel's Base Address of CommandBlock and ControlBlock.\r
+\r
+Arguments:\r
+ \r
+ AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV\r
+ IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR\r
+ \r
+Returns:\r
+ \r
+ None\r
+\r
+--*/ \r
+;\r
+\r
+/**\r
+ Installs Scsi Pass Thru and/or Ext Scsi Pass Thru \r
+ protocols based on feature flags. \r
+\r
+ @param Controller The controller handle to \r
+ install these protocols on.\r
+ @param AtapiScsiPrivate A pointer to the protocol private\r
+ data structure.\r
+\r
+ @retval EFI_SUCCESS The installation succeeds. \r
+ @retval other The installation fails. \r
+ \r
+**/\r
+EFI_STATUS\r
+InstallScsiPassThruProtocols (\r
+ IN EFI_HANDLE *ControllerHandle,\r
+ IN ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate\r
+ );\r
+\r
+#endif\r