]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
Add OptionRomPkg, it contains AtapiPassThru driver for the test purpose of Scsi Bus...
[mirror_edk2.git] / OptionRomPkg / AtapiPassThruDxe / AtapiPassThru.h
diff --git a/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h b/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.h
new file mode 100644 (file)
index 0000000..2187580
--- /dev/null
@@ -0,0 +1,1625 @@
+/** @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