]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
edk2: Remove packages moved to edk2-platforms
[mirror_edk2.git] / OptionRomPkg / AtapiPassThruDxe / AtapiPassThru.c
diff --git a/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c b/OptionRomPkg/AtapiPassThruDxe/AtapiPassThru.c
deleted file mode 100644 (file)
index 20de2bc..0000000
+++ /dev/null
@@ -1,3410 +0,0 @@
-/** @file\r
-  Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "AtapiPassThru.h"\r
-\r
-\r
-SCSI_COMMAND_SET     gEndTable = { 0xff, (DATA_DIRECTION) 0xff };\r
-\r
-///\r
-/// This table contains all the supported ATAPI commands.\r
-///\r
-SCSI_COMMAND_SET     gSupportedATAPICommands[] = {\r
-  { OP_INQUIRY,                     DataIn  },\r
-  { OP_LOAD_UNLOAD_CD,              NoData  },\r
-  { OP_MECHANISM_STATUS,            DataIn  },\r
-  { OP_MODE_SELECT_10,              DataOut },\r
-  { OP_MODE_SENSE_10,               DataIn  },\r
-  { OP_PAUSE_RESUME,                NoData  },\r
-  { OP_PLAY_AUDIO_10,               DataIn  },\r
-  { OP_PLAY_AUDIO_MSF,              DataIn  },\r
-  { OP_PLAY_CD,                     DataIn  },\r
-  { OP_PLAY_CD_MSF,                 DataIn  },\r
-  { OP_PREVENT_ALLOW_MEDIUM_REMOVAL,NoData  },\r
-  { OP_READ_10,                     DataIn  },\r
-  { OP_READ_12,                     DataIn  },\r
-  { OP_READ_CAPACITY,               DataIn  },\r
-  { OP_READ_CD,                     DataIn  },\r
-  { OP_READ_CD_MSF,                 DataIn  },\r
-  { OP_READ_HEADER,                 DataIn  },\r
-  { OP_READ_SUB_CHANNEL,            DataIn  },\r
-  { OP_READ_TOC,                    DataIn  },\r
-  { OP_REQUEST_SENSE,               DataIn  },\r
-  { OP_SCAN,                        NoData  },\r
-  { OP_SEEK_10,                     NoData  },\r
-  { OP_SET_CD_SPEED,                DataOut },\r
-  { OP_STOPPLAY_SCAN,               NoData  },\r
-  { OP_START_STOP_UNIT,             NoData  },\r
-  { OP_TEST_UNIT_READY,             NoData  },\r
-  { OP_FORMAT_UNIT,                 DataOut },\r
-  { OP_READ_FORMAT_CAPACITIES,      DataIn  },\r
-  { OP_VERIFY,                      DataOut },\r
-  { OP_WRITE_10,                    DataOut },\r
-  { OP_WRITE_12,                    DataOut },\r
-  { OP_WRITE_AND_VERIFY,            DataOut },\r
-  { 0xff,                           (DATA_DIRECTION) 0xff    }\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_MODE gScsiPassThruMode = {\r
-  L"ATAPI Controller",\r
-  L"ATAPI Channel",\r
-  4,\r
-  EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,\r
-  0\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_SCSI_PASS_THRU_PROTOCOL gScsiPassThruProtocolTemplate = {\r
-  &gScsiPassThruMode,\r
-  AtapiScsiPassThruFunction,\r
-  AtapiScsiPassThruGetNextDevice,\r
-  AtapiScsiPassThruBuildDevicePath,\r
-  AtapiScsiPassThruGetTargetLun,\r
-  AtapiScsiPassThruResetChannel,\r
-  AtapiScsiPassThruResetTarget\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_MODE gExtScsiPassThruMode = {\r
-  4,\r
-  EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,\r
-  0\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_EXT_SCSI_PASS_THRU_PROTOCOL gExtScsiPassThruProtocolTemplate = {\r
-  &gExtScsiPassThruMode,\r
-  AtapiExtScsiPassThruFunction,\r
-  AtapiExtScsiPassThruGetNextTargetLun,\r
-  AtapiExtScsiPassThruBuildDevicePath,\r
-  AtapiExtScsiPassThruGetTargetLun,\r
-  AtapiExtScsiPassThruResetChannel,\r
-  AtapiExtScsiPassThruResetTarget,\r
-  AtapiExtScsiPassThruGetNextTarget\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gAtapiScsiPassThruDriverBinding = {\r
-  AtapiScsiPassThruDriverBindingSupported,\r
-  AtapiScsiPassThruDriverBindingStart,\r
-  AtapiScsiPassThruDriverBindingStop,\r
-  0x10,\r
-  NULL,\r
-  NULL\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
-\r
-Routine Description:\r
-  Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
-  that has gEfiPciIoProtocolGuid installed and is IDE Controller it will be supported.\r
-\r
-Arguments:\r
-\r
-  This                - Protocol instance pointer.\r
-  Controller          - Handle of device to test\r
-  RemainingDevicePath - Not used\r
-\r
-Returns:\r
-    EFI_STATUS\r
-\r
---*/\r
-{\r
-  EFI_STATUS          Status;\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  PCI_TYPE00          Pci;\r
-\r
-\r
-  //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Use the PCI I/O Protocol to see if Controller is a IDE Controller that\r
-  // can be managed by this driver.  Read the PCI Configuration Header\r
-  // for this device.\r
-  //\r
-  Status = PciIo->Pci.Read (\r
-                        PciIo,\r
-                        EfiPciIoWidthUint32,\r
-                        0,\r
-                        sizeof (Pci) / sizeof (UINT32),\r
-                        &Pci\r
-                        );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiPciIoProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if (Pci.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE || Pci.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE) {\r
-\r
-    Status = EFI_UNSUPPORTED;\r
-  }\r
-\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiPciIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  return Status;\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
-\r
-Routine Description:\r
-  Create handles for IDE channels specified by RemainingDevicePath.\r
-  Install SCSI Pass Thru Protocol onto each created handle.\r
-\r
-Arguments:\r
-\r
-  This                - Protocol instance pointer.\r
-  Controller          - Handle of device to test\r
-  RemainingDevicePath - Not used\r
-\r
-Returns:\r
-    EFI_STATUS\r
-\r
---*/\r
-{\r
-  EFI_STATUS          Status;\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  UINT64              Supports;\r
-  UINT64              OriginalPciAttributes;\r
-  BOOLEAN             PciAttributesSaved;\r
-\r
-  PciIo = NULL;\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  PciAttributesSaved = FALSE;\r
-  //\r
-  // Save original PCI attributes\r
-  //\r
-  Status = PciIo->Attributes (\r
-                    PciIo,\r
-                    EfiPciIoAttributeOperationGet,\r
-                    0,\r
-                    &OriginalPciAttributes\r
-                    );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-  PciAttributesSaved = TRUE;\r
-\r
-  Status = PciIo->Attributes (\r
-                    PciIo,\r
-                    EfiPciIoAttributeOperationSupported,\r
-                    0,\r
-                    &Supports\r
-                    );\r
-  if (!EFI_ERROR (Status)) {\r
-    Supports &= (EFI_PCI_DEVICE_ENABLE               |\r
-                 EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |\r
-                 EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);\r
-    Status = PciIo->Attributes (\r
-                      PciIo,\r
-                      EfiPciIoAttributeOperationEnable,\r
-                      Supports,\r
-                      NULL\r
-                      );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Create SCSI Pass Thru instance for the IDE channel.\r
-  //\r
-  Status = RegisterAtapiScsiPassThru (This, Controller, PciIo, OriginalPciAttributes);\r
-\r
-Done:\r
-  if (EFI_ERROR (Status)) {\r
-    if (PciAttributesSaved == TRUE) {\r
-      //\r
-      // Restore original PCI attributes\r
-      //\r
-      PciIo->Attributes (\r
-                      PciIo,\r
-                      EfiPciIoAttributeOperationSet,\r
-                      OriginalPciAttributes,\r
-                      NULL\r
-                      );\r
-    }\r
-\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiPciIoProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-  }\r
-\r
-  return Status;\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
-Routine Description:\r
-\r
-  Stop this driver on ControllerHandle. Support stopping any child handles\r
-  created by this driver.\r
-\r
-Arguments:\r
-\r
-  This              - Protocol instance pointer.\r
-  Controller        - Handle of device to stop driver on\r
-  NumberOfChildren  - Number of Children in the ChildHandleBuffer\r
-  ChildHandleBuffer - List of handles for the children we need to stop.\r
-\r
-Returns:\r
-\r
-    EFI_STATUS\r
-\r
---*/\r
-{\r
-  EFI_STATUS                      Status;\r
-  EFI_SCSI_PASS_THRU_PROTOCOL     *ScsiPassThru;\r
-  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;\r
-  ATAPI_SCSI_PASS_THRU_DEV        *AtapiScsiPrivate;\r
-\r
-  if (FeaturePcdGet (PcdSupportScsiPassThru)) {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiScsiPassThruProtocolGuid,\r
-                    (VOID **) &ScsiPassThru,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (ScsiPassThru);\r
-    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {\r
-      Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                      Controller,\r
-                      &gEfiScsiPassThruProtocolGuid,\r
-                      &AtapiScsiPrivate->ScsiPassThru,\r
-                      &gEfiExtScsiPassThruProtocolGuid,\r
-                      &AtapiScsiPrivate->ExtScsiPassThru,\r
-                      NULL\r
-                      );\r
-    } else {\r
-      Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                      Controller,\r
-                      &gEfiScsiPassThruProtocolGuid,\r
-                      &AtapiScsiPrivate->ScsiPassThru,\r
-                      NULL\r
-                      );\r
-    }\r
-  } else {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiExtScsiPassThruProtocolGuid,\r
-                    (VOID **) &ExtScsiPassThru,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (ExtScsiPassThru);\r
-    Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                    Controller,\r
-                    &gEfiExtScsiPassThruProtocolGuid,\r
-                    &AtapiScsiPrivate->ExtScsiPassThru,\r
-                    NULL\r
-                    );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Restore original PCI attributes\r
-  //\r
-  AtapiScsiPrivate->PciIo->Attributes (\r
-                  AtapiScsiPrivate->PciIo,\r
-                  EfiPciIoAttributeOperationSet,\r
-                  AtapiScsiPrivate->OriginalPciAttributes,\r
-                  NULL\r
-                  );\r
-\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiPciIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  gBS->FreePool (AtapiScsiPrivate);\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_STATUS                Status;\r
-  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;\r
-  IDE_REGISTERS_BASE_ADDR   IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];\r
-\r
-  AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));\r
-  if (AtapiScsiPrivate == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;\r
-  AtapiScsiPrivate->Handle    = Controller;\r
-\r
-  //\r
-  // will reset the IoPort inside each API function.\r
-  //\r
-  AtapiScsiPrivate->IoPort                = NULL;\r
-  AtapiScsiPrivate->PciIo                 = PciIo;\r
-  AtapiScsiPrivate->OriginalPciAttributes = OriginalPciAttributes;\r
-\r
-  //\r
-  // Obtain IDE IO port registers' base addresses\r
-  //\r
-  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  InitAtapiIoPortRegisters(AtapiScsiPrivate, IdeRegsBaseAddr);\r
-\r
-  //\r
-  // Initialize the LatestTargetId to MAX_TARGET_ID.\r
-  //\r
-  AtapiScsiPrivate->LatestTargetId  = MAX_TARGET_ID;\r
-  AtapiScsiPrivate->LatestLun       = 0;\r
-\r
-  Status = InstallScsiPassThruProtocols (&Controller, AtapiScsiPrivate);\r
-\r
-  return Status;\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
-  ATAPI_SCSI_PASS_THRU_DEV               *AtapiScsiPrivate;\r
-  EFI_STATUS                             Status;\r
-\r
-  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Target is not allowed beyond MAX_TARGET_ID\r
-  //\r
-  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // check the data fields in Packet parameter.\r
-  //\r
-  Status = CheckSCSIRequestPacket (Packet);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If Request Packet targets at the IDE channel itself,\r
-  // do nothing.\r
-  //\r
-  if (Target == This->Mode->AdapterId) {\r
-    Packet->TransferLength = 0;\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // According to Target ID, reset the Atapi I/O Register mapping\r
-  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],\r
-  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]\r
-  //\r
-  if ((Target / 2) == 0) {\r
-    Target = Target % 2;\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];\r
-  } else {\r
-    Target = Target % 2;\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];\r
-  }\r
-\r
-  //\r
-  // the ATAPI SCSI interface does not support non-blocking I/O\r
-  // ignore the Event parameter\r
-  //\r
-  // Performs blocking I/O.\r
-  //\r
-  Status = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, Packet);\r
-  return Status;\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
-  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;\r
-\r
-  //\r
-  // Retrieve Device Private Data Structure.\r
-  //\r
-  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Check whether Target is valid.\r
-  //\r
-  if (Target == NULL || Lun == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((*Target != 0xFFFFFFFF) &&\r
-      ((*Target != AtapiScsiPrivate->LatestTargetId) ||\r
-      (*Lun != AtapiScsiPrivate->LatestLun))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (*Target == MAX_TARGET_ID) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (*Target == 0xFFFFFFFF) {\r
-    *Target = 0;\r
-  } else {\r
-    *Target = AtapiScsiPrivate->LatestTargetId + 1;\r
-  }\r
-\r
-  *Lun = 0;\r
-\r
-  //\r
-  // Update the LatestTargetId.\r
-  //\r
-  AtapiScsiPrivate->LatestTargetId  = *Target;\r
-  AtapiScsiPrivate->LatestLun       = *Lun;\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_DEV_PATH              *Node;\r
-\r
-\r
-  //\r
-  // Validate parameters passed in.\r
-  //\r
-\r
-  if (DevicePath == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // can not build device path for the SCSI Host Controller.\r
-  //\r
-  if ((Target > (MAX_TARGET_ID - 1)) || (Lun != 0)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));\r
-  if (Node == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;\r
-  Node->DevPath.SubType = MSG_ATAPI_DP;\r
-  SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));\r
-\r
-  Node->Atapi.PrimarySecondary  = (UINT8) (Target / 2);\r
-  Node->Atapi.SlaveMaster       = (UINT8) (Target % 2);\r
-  Node->Atapi.Lun               = (UINT16) Lun;\r
-\r
-  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_DEV_PATH  *Node;\r
-\r
-  //\r
-  // Validate parameters passed in.\r
-  //\r
-  if (DevicePath == NULL || Target == NULL || Lun == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH\r
-  //\r
-  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||\r
-      (DevicePath->SubType != MSG_ATAPI_DP) ||\r
-      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Node    = (EFI_DEV_PATH *) DevicePath;\r
-\r
-  *Target = Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster;\r
-  *Lun    = Node->Atapi.Lun;\r
-\r
-  if (*Target > (MAX_TARGET_ID - 1) || *Lun != 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8                     DeviceControlValue;\r
-  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;\r
-  UINT8                     Index;\r
-  BOOLEAN                   ResetFlag;\r
-\r
-  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-  ResetFlag = FALSE;\r
-\r
-  //\r
-  // Reset both Primary channel and Secondary channel.\r
-  // so, the IoPort pointer must point to the right I/O Register group\r
-  //\r
-  for (Index = 0; Index < 2; Index++) {\r
-    //\r
-    // Reset\r
-    //\r
-    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];\r
-\r
-    DeviceControlValue        = 0;\r
-    //\r
-    // set SRST bit to initiate soft reset\r
-    //\r
-    DeviceControlValue |= SRST;\r
-    //\r
-    // disable Interrupt\r
-    //\r
-    DeviceControlValue |= BIT1;\r
-    WritePortB (\r
-      AtapiScsiPrivate->PciIo,\r
-      AtapiScsiPrivate->IoPort->Alt.DeviceControl,\r
-      DeviceControlValue\r
-      );\r
-\r
-    //\r
-    // Wait 10us\r
-    //\r
-    gBS->Stall (10);\r
-\r
-    //\r
-    // Clear SRST bit\r
-    // 0xfb:1111,1011\r
-    //\r
-    DeviceControlValue &= 0xfb;\r
-\r
-    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);\r
-\r
-    //\r
-    // slave device needs at most 31s to clear BSY\r
-    //\r
-    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {\r
-      ResetFlag = TRUE;\r
-    }\r
-  }\r
-\r
-  if (ResetFlag) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  return EFI_TIMEOUT;\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
-  ATAPI_SCSI_PASS_THRU_DEV  *AtapiScsiPrivate;\r
-  UINT8                     Command;\r
-  UINT8                     DeviceSelect;\r
-\r
-  AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  if ((Target > MAX_TARGET_ID) || (Lun != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Directly return EFI_SUCCESS if want to reset the host controller\r
-  //\r
-  if (Target == This->Mode->AdapterId) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // According to Target ID, reset the Atapi I/O Register mapping\r
-  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],\r
-  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]\r
-  //\r
-  if ((Target / 2) == 0) {\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];\r
-  } else {\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];\r
-  }\r
-\r
-  //\r
-  // for ATAPI device, no need to wait DRDY ready after device selecting.\r
-  //\r
-  // bit7 and bit5 are both set to 1 for backward compatibility\r
-  //\r
-  DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Target << 4)));\r
-  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);\r
-\r
-  Command = ATAPI_SOFT_RESET_CMD;\r
-  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);\r
-\r
-  //\r
-  // BSY clear is the only status return to the host by the device\r
-  // when reset is complete.\r
-  // slave device needs at most 31s to clear BSY\r
-  //\r
-  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  //\r
-  // stall 5 seconds to make the device status stable\r
-  //\r
-  gBS->Stall (5000000);\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_STATUS                          Status;\r
-  ATAPI_SCSI_PASS_THRU_DEV            *AtapiScsiPrivate;\r
-  UINT8                                TargetId;\r
-\r
-  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // For ATAPI device, UINT8 is enough to represent the SCSI ID on channel.\r
-  //\r
-  TargetId = Target[0];\r
-\r
-  //\r
-  // Target is not allowed beyond MAX_TARGET_ID\r
-  //\r
-  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // check the data fields in Packet parameter.\r
-  //\r
-  Status = CheckExtSCSIRequestPacket (Packet);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // If Request Packet targets at the IDE channel itself,\r
-  // do nothing.\r
-  //\r
-  if (TargetId == (UINT8)This->Mode->AdapterId) {\r
-    Packet->InTransferLength = Packet->OutTransferLength = 0;\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // According to Target ID, reset the Atapi I/O Register mapping\r
-  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],\r
-  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]\r
-  //\r
-  if ((TargetId / 2) == 0) {\r
-    TargetId = (UINT8) (TargetId % 2);\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];\r
-  } else {\r
-    TargetId = (UINT8) (TargetId % 2);\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];\r
-  }\r
-\r
-  //\r
-  // the ATAPI SCSI interface does not support non-blocking I/O\r
-  // ignore the Event parameter\r
-  //\r
-  // Performs blocking I/O.\r
-  //\r
-  Status = SubmitExtBlockingIoCommand (AtapiScsiPrivate, TargetId, Packet);\r
-  return Status;\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
-  UINT8                          ByteIndex;\r
-  UINT8                          TargetId;\r
-  UINT8                          ScsiId[TARGET_MAX_BYTES];\r
-  ATAPI_SCSI_PASS_THRU_DEV       *AtapiScsiPrivate;\r
-\r
-  //\r
-  // Retrieve Device Private Data Structure.\r
-  //\r
-  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Check whether Target is valid.\r
-  //\r
-  if (*Target == NULL || Lun == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);\r
-\r
-  TargetId = (*Target)[0];\r
-\r
-  //\r
-  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.\r
-  //\r
-  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {\r
-    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {\r
-      if ((*Target)[ByteIndex] != 0) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-\r
-  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&\r
-      ((TargetId != AtapiScsiPrivate->LatestTargetId) ||\r
-      (*Lun != AtapiScsiPrivate->LatestLun))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (TargetId == MAX_TARGET_ID) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0) {\r
-    SetMem (*Target, TARGET_MAX_BYTES,0);\r
-  } else {\r
-    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);\r
-  }\r
-\r
-  *Lun = 0;\r
-\r
-  //\r
-  // Update the LatestTargetId.\r
-  //\r
-  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];\r
-  AtapiScsiPrivate->LatestLun       = *Lun;\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_DEV_PATH                   *Node;\r
-  UINT8                          TargetId;\r
-\r
-  TargetId = Target[0];\r
-\r
-  //\r
-  // Validate parameters passed in.\r
-  //\r
-\r
-  if (DevicePath == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // can not build device path for the SCSI Host Controller.\r
-  //\r
-  if ((TargetId > (MAX_TARGET_ID - 1)) || (Lun != 0)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  Node = AllocateZeroPool (sizeof (EFI_DEV_PATH));\r
-  if (Node == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;\r
-  Node->DevPath.SubType = MSG_ATAPI_DP;\r
-  SetDevicePathNodeLength (&Node->DevPath, sizeof (ATAPI_DEVICE_PATH));\r
-\r
-  Node->Atapi.PrimarySecondary  = (UINT8) (TargetId / 2);\r
-  Node->Atapi.SlaveMaster       = (UINT8) (TargetId % 2);\r
-  Node->Atapi.Lun               = (UINT16) Lun;\r
-\r
-  *DevicePath                   = (EFI_DEVICE_PATH_PROTOCOL *) Node;\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_DEV_PATH  *Node;\r
-\r
-  //\r
-  // Validate parameters passed in.\r
-  //\r
-  if (DevicePath == NULL || Target == NULL || Lun == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH\r
-  //\r
-  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||\r
-      (DevicePath->SubType != MSG_ATAPI_DP) ||\r
-      (DevicePathNodeLength(DevicePath) != sizeof(ATAPI_DEVICE_PATH))) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  ZeroMem (*Target, TARGET_MAX_BYTES);\r
-\r
-  Node    = (EFI_DEV_PATH *) DevicePath;\r
-\r
-  (*Target)[0] = (UINT8) (Node->Atapi.PrimarySecondary * 2 + Node->Atapi.SlaveMaster);\r
-  *Lun    = Node->Atapi.Lun;\r
-\r
-  if ((*Target)[0] > (MAX_TARGET_ID - 1) || *Lun != 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8                         DeviceControlValue;\r
-  UINT8                         Index;\r
-  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;\r
-  BOOLEAN                       ResetFlag;\r
-\r
-  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-  ResetFlag = FALSE;\r
-  //\r
-  // Reset both Primary channel and Secondary channel.\r
-  // so, the IoPort pointer must point to the right I/O Register group\r
-  // And if there is a channel reset successfully, return EFI_SUCCESS.\r
-  //\r
-  for (Index = 0; Index < 2; Index++) {\r
-    //\r
-    // Reset\r
-    //\r
-    AtapiScsiPrivate->IoPort  = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];\r
-\r
-    DeviceControlValue        = 0;\r
-    //\r
-    // set SRST bit to initiate soft reset\r
-    //\r
-    DeviceControlValue |= SRST;\r
-    //\r
-    // disable Interrupt\r
-    //\r
-    DeviceControlValue |= BIT1;\r
-    WritePortB (\r
-      AtapiScsiPrivate->PciIo,\r
-      AtapiScsiPrivate->IoPort->Alt.DeviceControl,\r
-      DeviceControlValue\r
-      );\r
-\r
-    //\r
-    // Wait 10us\r
-    //\r
-    gBS->Stall (10);\r
-\r
-    //\r
-    // Clear SRST bit\r
-    // 0xfb:1111,1011\r
-    //\r
-    DeviceControlValue &= 0xfb;\r
-\r
-    WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);\r
-\r
-    //\r
-    // slave device needs at most 31s to clear BSY\r
-    //\r
-    if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {\r
-      ResetFlag = TRUE;\r
-    }\r
-  }\r
-\r
-  if (ResetFlag) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  return EFI_TIMEOUT;\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
-  UINT8                         Command;\r
-  UINT8                         DeviceSelect;\r
-  UINT8                         TargetId;\r
-  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;\r
-\r
-  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-  TargetId = Target[0];\r
-\r
-  if ((TargetId > MAX_TARGET_ID) || (Lun != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Directly return EFI_SUCCESS if want to reset the host controller\r
-  //\r
-  if (TargetId == This->Mode->AdapterId) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // According to Target ID, reset the Atapi I/O Register mapping\r
-  // (Target Id in [0,1] area, using AtapiIoPortRegisters[0],\r
-  //  Target Id in [2,3] area, using AtapiIoPortRegisters[1]\r
-  //\r
-  if ((TargetId / 2) == 0) {\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];\r
-  } else {\r
-    AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];\r
-  }\r
-\r
-  //\r
-  // for ATAPI device, no need to wait DRDY ready after device selecting.\r
-  //\r
-  // bit7 and bit5 are both set to 1 for backward compatibility\r
-  //\r
-  DeviceSelect = (UINT8) ((BIT7 | BIT5) | (TargetId << 4));\r
-  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Head, DeviceSelect);\r
-\r
-  Command = ATAPI_SOFT_RESET_CMD;\r
-  WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg.Command, Command);\r
-\r
-  //\r
-  // BSY clear is the only status return to the host by the device\r
-  // when reset is complete.\r
-  // slave device needs at most 31s to clear BSY\r
-  //\r
-  if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  //\r
-  // stall 5 seconds to make the device status stable\r
-  //\r
-  gBS->Stall (5000000);\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8                         TargetId;\r
-  UINT8                         ScsiId[TARGET_MAX_BYTES];\r
-  ATAPI_SCSI_PASS_THRU_DEV      *AtapiScsiPrivate;\r
-  UINT8                         ByteIndex;\r
-\r
-  //\r
-  // Retrieve Device Private Data Structure.\r
-  //\r
-  AtapiScsiPrivate = ATAPI_EXT_SCSI_PASS_THRU_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Check whether Target is valid.\r
-  //\r
-  if (*Target == NULL ) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  TargetId = (*Target)[0];\r
-  SetMem (ScsiId, TARGET_MAX_BYTES, 0xFF);\r
-\r
-  //\r
-  // For ATAPI device, we use UINT8 to represent the SCSI ID on channel.\r
-  //\r
-  if (CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) {\r
-    for (ByteIndex = 1; ByteIndex < TARGET_MAX_BYTES; ByteIndex++) {\r
-      if ((*Target)[ByteIndex] != 0) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-\r
-  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) != 0) &&(TargetId != AtapiScsiPrivate->LatestTargetId)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (TargetId == MAX_TARGET_ID) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if ((CompareMem(*Target, ScsiId, TARGET_MAX_BYTES) == 0)) {\r
-    SetMem (*Target, TARGET_MAX_BYTES, 0);\r
-  } else {\r
-    (*Target)[0] = (UINT8) (AtapiScsiPrivate->LatestTargetId + 1);\r
-  }\r
-\r
-  //\r
-  // Update the LatestTargetId.\r
-  //\r
-  AtapiScsiPrivate->LatestTargetId  = (*Target)[0];\r
-  AtapiScsiPrivate->LatestLun       = 0;\r
-\r
-  return EFI_SUCCESS;\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
-  EFI_STATUS  Status;\r
-  PCI_TYPE00  PciData;\r
-\r
-  Status = PciIo->Pci.Read (\r
-                        PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        0,\r
-                        sizeof (PciData),\r
-                        &PciData\r
-                        );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {\r
-    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  = 0x1f0;\r
-    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  = 0x3f6;\r
-  } else {\r
-    //\r
-    // The BARs should be of IO type\r
-    //\r
-    if ((PciData.Device.Bar[0] & BIT0) == 0 ||\r
-        (PciData.Device.Bar[1] & BIT0) == 0) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr  =\r
-    (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);\r
-    IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr  =\r
-    (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);\r
-  }\r
-\r
-  if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {\r
-    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  = 0x170;\r
-    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  = 0x376;\r
-  } else {\r
-    //\r
-    // The BARs should be of IO type\r
-    //\r
-    if ((PciData.Device.Bar[2] & BIT0) == 0 ||\r
-        (PciData.Device.Bar[3] & BIT0) == 0) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr  =\r
-    (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);\r
-    IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr  =\r
-    (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8               IdeChannel;\r
-  UINT16              CommandBlockBaseAddr;\r
-  UINT16              ControlBlockBaseAddr;\r
-  IDE_BASE_REGISTERS  *RegisterPointer;\r
-\r
-\r
-  for (IdeChannel = 0; IdeChannel < ATAPI_MAX_CHANNEL; IdeChannel++) {\r
-\r
-    RegisterPointer =  &AtapiScsiPrivate->AtapiIoPortRegisters[IdeChannel];\r
-\r
-    //\r
-    // Initialize IDE IO port addresses, including Command Block registers\r
-    // and Control Block registers\r
-    //\r
-    CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
-    ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
-\r
-    RegisterPointer->Data = CommandBlockBaseAddr;\r
-    (*(UINT16 *) &RegisterPointer->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
-    RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
-    RegisterPointer->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
-    RegisterPointer->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
-    RegisterPointer->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
-    RegisterPointer->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
-    (*(UINT16 *) &RegisterPointer->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
-\r
-    (*(UINT16 *) &RegisterPointer->Alt) = ControlBlockBaseAddr;\r
-    RegisterPointer->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
-  }\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
-  if (Packet == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!ValidCdbLength (Packet->CdbLength)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Packet->Cdb == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Checks whether the request command is supported.\r
-  //\r
-  if (!IsCommandValid (Packet)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8 Index;\r
-  UINT8 *OpCode;\r
-  UINT8 ArrayLen;\r
-\r
-  OpCode = (UINT8 *) (Packet->Cdb);\r
-  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));\r
-\r
-  for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {\r
-\r
-    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {\r
-      //\r
-      // Check whether the requested Command is supported by this driver\r
-      //\r
-      if (Packet->DataDirection == DataIn) {\r
-        //\r
-        // Check whether the requested data direction conforms to\r
-        // what it should be.\r
-        //\r
-        if (gSupportedATAPICommands[Index].Direction == DataOut) {\r
-          return FALSE;\r
-        }\r
-      }\r
-\r
-      if (Packet->DataDirection == DataOut) {\r
-        //\r
-        // Check whether the requested data direction conforms to\r
-        // what it should be.\r
-        //\r
-        if (gSupportedATAPICommands[Index].Direction == DataIn) {\r
-          return FALSE;\r
-        }\r
-      }\r
-\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\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
-  UINT8       PacketCommand[12];\r
-  UINT64      TimeoutInMicroSeconds;\r
-  EFI_STATUS  PacketCommandStatus;\r
-\r
-  //\r
-  // Fill ATAPI Command Packet according to CDB\r
-  //\r
-  ZeroMem (&PacketCommand, 12);\r
-  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);\r
-\r
-  //\r
-  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.\r
-  //\r
-  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);\r
-\r
-  //\r
-  // Submit ATAPI Command Packet\r
-  //\r
-  PacketCommandStatus = AtapiPacketCommand (\r
-                          AtapiScsiPrivate,\r
-                          Target,\r
-                          PacketCommand,\r
-                          Packet->DataBuffer,\r
-                          &(Packet->TransferLength),\r
-                          (DATA_DIRECTION) Packet->DataDirection,\r
-                          TimeoutInMicroSeconds\r
-                          );\r
-  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {\r
-    Packet->SenseDataLength = 0;\r
-    return PacketCommandStatus;\r
-  }\r
-\r
-  //\r
-  // Return SenseData if PacketCommandStatus matches\r
-  // the following return codes.\r
-  //\r
-  if ((PacketCommandStatus ==  EFI_BAD_BUFFER_SIZE) ||\r
-      (PacketCommandStatus == EFI_DEVICE_ERROR) ||\r
-      (PacketCommandStatus == EFI_TIMEOUT)) {\r
-\r
-    //\r
-    // avoid submit request sense command continuously.\r
-    //\r
-    if (PacketCommand[0] == OP_REQUEST_SENSE) {\r
-      Packet->SenseDataLength = 0;\r
-      return PacketCommandStatus;\r
-    }\r
-\r
-    RequestSenseCommand (\r
-      AtapiScsiPrivate,\r
-      Target,\r
-      Packet->Timeout,\r
-      Packet->SenseData,\r
-      &Packet->SenseDataLength\r
-      );\r
-  }\r
-\r
-  return PacketCommandStatus;\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
-  Submit request sense command\r
-\r
-Arguments:\r
-\r
-  AtapiScsiPrivate  - The pointer 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
-  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;\r
-  UINT8                                   Cdb[12];\r
-  EFI_STATUS                              Status;\r
-\r
-  ZeroMem (&Packet, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
-  ZeroMem (Cdb, 12);\r
-\r
-  Cdb[0]                = OP_REQUEST_SENSE;\r
-  Cdb[4]                = (UINT8) (*SenseDataLength);\r
-\r
-  Packet.Timeout        = Timeout;\r
-  Packet.DataBuffer     = SenseData;\r
-  Packet.SenseData      = NULL;\r
-  Packet.Cdb            = Cdb;\r
-  Packet.TransferLength = *SenseDataLength;\r
-  Packet.CdbLength      = 12;\r
-  Packet.DataDirection  = DataIn;\r
-\r
-  Status                = SubmitBlockingIoCommand (AtapiScsiPrivate, Target, &Packet);\r
-  *SenseDataLength      = (UINT8) (Packet.TransferLength);\r
-  return Status;\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
-  if (Packet == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!ValidCdbLength (Packet->CdbLength)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Packet->Cdb == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Checks whether the request command is supported.\r
-  //\r
-  if (!IsExtCommandValid (Packet)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8 Index;\r
-  UINT8 *OpCode;\r
-  UINT8 ArrayLen;\r
-\r
-  OpCode = (UINT8 *) (Packet->Cdb);\r
-  ArrayLen = (UINT8) (ARRAY_SIZE (gSupportedATAPICommands));\r
-\r
-  for (Index = 0; (Index < ArrayLen) && (CompareMem (&gSupportedATAPICommands[Index], &gEndTable, sizeof (SCSI_COMMAND_SET)) != 0); Index++) {\r
-\r
-    if (*OpCode == gSupportedATAPICommands[Index].OpCode) {\r
-      //\r
-      // Check whether the requested Command is supported by this driver\r
-      //\r
-      if (Packet->DataDirection == DataIn) {\r
-        //\r
-        // Check whether the requested data direction conforms to\r
-        // what it should be.\r
-        //\r
-        if (gSupportedATAPICommands[Index].Direction == DataOut) {\r
-          return FALSE;\r
-        }\r
-      }\r
-\r
-      if (Packet->DataDirection == DataOut) {\r
-        //\r
-        // Check whether the requested data direction conforms to\r
-        // what it should be.\r
-        //\r
-        if (gSupportedATAPICommands[Index].Direction == DataIn) {\r
-          return FALSE;\r
-        }\r
-      }\r
-\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\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
-  UINT8       PacketCommand[12];\r
-  UINT64      TimeoutInMicroSeconds;\r
-  EFI_STATUS  PacketCommandStatus;\r
-\r
-  //\r
-  // Fill ATAPI Command Packet according to CDB\r
-  //\r
-  ZeroMem (&PacketCommand, 12);\r
-  CopyMem (&PacketCommand, Packet->Cdb, Packet->CdbLength);\r
-\r
-  //\r
-  // Timeout is 100ns unit, convert it to 1000ns (1us) unit.\r
-  //\r
-  TimeoutInMicroSeconds = DivU64x32 (Packet->Timeout, (UINT32) 10);\r
-\r
-  //\r
-  // Submit ATAPI Command Packet\r
-  //\r
-  if (Packet->DataDirection == DataIn) {\r
-    PacketCommandStatus = AtapiPacketCommand (\r
-                              AtapiScsiPrivate,\r
-                              Target,\r
-                              PacketCommand,\r
-                              Packet->InDataBuffer,\r
-                              &(Packet->InTransferLength),\r
-                              DataIn,\r
-                              TimeoutInMicroSeconds\r
-                              );\r
-  } else {\r
-\r
-    PacketCommandStatus = AtapiPacketCommand (\r
-                            AtapiScsiPrivate,\r
-                            Target,\r
-                            PacketCommand,\r
-                            Packet->OutDataBuffer,\r
-                            &(Packet->OutTransferLength),\r
-                            DataOut,\r
-                            TimeoutInMicroSeconds\r
-                            );\r
-  }\r
-\r
-  if (!EFI_ERROR (PacketCommandStatus) || (Packet->SenseData == NULL)) {\r
-    Packet->SenseDataLength = 0;\r
-    return PacketCommandStatus;\r
-  }\r
-\r
-  //\r
-  // Return SenseData if PacketCommandStatus matches\r
-  // the following return codes.\r
-  //\r
-  if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||\r
-      (PacketCommandStatus == EFI_DEVICE_ERROR) ||\r
-      (PacketCommandStatus == EFI_TIMEOUT)) {\r
-\r
-    //\r
-    // avoid submit request sense command continuously.\r
-    //\r
-    if (PacketCommand[0] == OP_REQUEST_SENSE) {\r
-      Packet->SenseDataLength = 0;\r
-      return PacketCommandStatus;\r
-    }\r
-\r
-    RequestSenseCommand (\r
-      AtapiScsiPrivate,\r
-      Target,\r
-      Packet->Timeout,\r
-      Packet->SenseData,\r
-      &Packet->SenseDataLength\r
-      );\r
-  }\r
-\r
-  return PacketCommandStatus;\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
-  UINT16      *CommandIndex;\r
-  UINT8       Count;\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // Set all the command parameters by fill related registers.\r
-  // Before write to all the following registers, BSY must be 0.\r
-  //\r
-  Status = StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-\r
-  //\r
-  // Select device via Device/Head Register.\r
-  // "Target = 0" indicates device 0; "Target = 1" indicates device 1\r
-  //\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->Head,\r
-    (UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)\r
-    );\r
-\r
-  //\r
-  // Set all the command parameters by fill related registers.\r
-  // Before write to all the following registers, BSY DRQ must be 0.\r
-  //\r
-  Status =  StatusDRQClear(AtapiScsiPrivate,  TimeoutInMicroSeconds);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (Status == EFI_ABORTED) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-    *ByteCount = 0;\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // No OVL; No DMA (by setting feature register)\r
-  //\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->Reg1.Feature,\r
-    0x00\r
-    );\r
-\r
-  //\r
-  // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device\r
-  // determine how much data should be transfered.\r
-  //\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->CylinderLsb,\r
-    (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)\r
-    );\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->CylinderMsb,\r
-    (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)\r
-    );\r
-\r
-  //\r
-  //  DEFAULT_CTL:0x0a (0000,1010)\r
-  //  Disable interrupt\r
-  //\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->Alt.DeviceControl,\r
-    DEFAULT_CTL\r
-    );\r
-\r
-  //\r
-  // Send Packet command to inform device\r
-  // that the following data bytes are command packet.\r
-  //\r
-  WritePortB (\r
-    AtapiScsiPrivate->PciIo,\r
-    AtapiScsiPrivate->IoPort->Reg.Command,\r
-    PACKET_CMD\r
-    );\r
-\r
-  //\r
-  // Before data transfer, BSY should be 0 and DRQ should be 1.\r
-  // if they are not in specified time frame,\r
-  // retrieve Sense Key from Error Register before return.\r
-  //\r
-  Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);\r
-  if (EFI_ERROR (Status)) {\r
-    if (Status == EFI_ABORTED) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-\r
-    *ByteCount = 0;\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Send out command packet\r
-  //\r
-  CommandIndex = (UINT16 *) PacketCommand;\r
-  for (Count = 0; Count < 6; Count++, CommandIndex++) {\r
-    WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *CommandIndex);\r
-  }\r
-\r
-  //\r
-  // call AtapiPassThruPioReadWriteData() function to get\r
-  // requested transfer data form device.\r
-  //\r
-  return AtapiPassThruPioReadWriteData (\r
-          AtapiScsiPrivate,\r
-          Buffer,\r
-          ByteCount,\r
-          Direction,\r
-          TimeoutInMicroSeconds\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
-  UINT32      Index;\r
-  UINT32      RequiredWordCount;\r
-  UINT32      ActualWordCount;\r
-  UINT32      WordCount;\r
-  EFI_STATUS  Status;\r
-  UINT16      *ptrBuffer;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // Non Data transfer request is also supported.\r
-  //\r
-  if (*ByteCount == 0 || Buffer == NULL) {\r
-    *ByteCount = 0;\r
-    if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds))) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
-  ptrBuffer         = Buffer;\r
-  RequiredWordCount = *ByteCount / 2;\r
-\r
-  //\r
-  // ActuralWordCount means the word count of data really transfered.\r
-  //\r
-  ActualWordCount = 0;\r
-\r
-  while (ActualWordCount < RequiredWordCount) {\r
-    //\r
-    // before each data transfer stream, the host should poll DRQ bit ready,\r
-    // which indicates device's ready for data transfer .\r
-    //\r
-    Status = StatusDRQReady (AtapiScsiPrivate, TimeoutInMicroSeconds);\r
-    if (EFI_ERROR (Status)) {\r
-      *ByteCount = ActualWordCount * 2;\r
-\r
-      AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);\r
-\r
-      if (ActualWordCount == 0) {\r
-        return EFI_DEVICE_ERROR;\r
-      }\r
-      //\r
-      // ActualWordCount > 0\r
-      //\r
-      if (ActualWordCount < RequiredWordCount) {\r
-        return EFI_BAD_BUFFER_SIZE;\r
-      }\r
-    }\r
-    //\r
-    // get current data transfer size from Cylinder Registers.\r
-    //\r
-    WordCount = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderMsb) << 8;\r
-    WordCount = WordCount | ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->CylinderLsb);\r
-    WordCount = WordCount & 0xffff;\r
-    WordCount /= 2;\r
-\r
-    //\r
-    // perform a series data In/Out.\r
-    //\r
-    for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) {\r
-\r
-      if (Direction == DataIn) {\r
-\r
-        *ptrBuffer = ReadPortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data);\r
-      } else {\r
-\r
-        WritePortW (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Data, *ptrBuffer);\r
-      }\r
-\r
-      ptrBuffer++;\r
-\r
-    }\r
-  }\r
-  //\r
-  // After data transfer is completed, normally, DRQ bit should clear.\r
-  //\r
-  StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);\r
-\r
-  //\r
-  // read status register to check whether error happens.\r
-  //\r
-  Status      = AtapiPassThruCheckErrorStatus (AtapiScsiPrivate);\r
-\r
-  *ByteCount  = ActualWordCount * 2;\r
-\r
-  return Status;\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
-  UINT8 Data;\r
-\r
-  Data = 0;\r
-  PciIo->Io.Read (\r
-              PciIo,\r
-              EfiPciIoWidthUint8,\r
-              EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
-              1,\r
-              &Data\r
-              );\r
-  return Data;\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
-  UINT16  Data;\r
-\r
-  Data = 0;\r
-  PciIo->Io.Read (\r
-              PciIo,\r
-              EfiPciIoWidthUint16,\r
-              EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
-              1,\r
-              &Data\r
-              );\r
-  return Data;\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
-  PciIo->Io.Write (\r
-              PciIo,\r
-              EfiPciIoWidthUint8,\r
-              EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
-              1,\r
-              &Data\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
-  PciIo->Io.Write (\r
-              PciIo,\r
-              EfiPciIoWidthUint16,\r
-              EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
-              1,\r
-              &Data\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
-  UINT64  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-\r
-    StatusRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg.Status\r
-                      );\r
-\r
-    //\r
-    // wait for BSY == 0 and DRQ == 0\r
-    //\r
-    if ((StatusRegister & (DRQ | BSY)) == 0) {\r
-      break;\r
-    }\r
-    //\r
-    // check whether the command is aborted by the device\r
-    //\r
-    if ((StatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-    //\r
-    //  Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   AltStatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-\r
-    AltStatusRegister = ReadPortB (\r
-                          AtapiScsiPrivate->PciIo,\r
-                          AtapiScsiPrivate->IoPort->Alt.AltStatus\r
-                          );\r
-\r
-    //\r
-    // wait for BSY == 0 and DRQ == 0\r
-    //\r
-    if ((AltStatusRegister & (DRQ | BSY)) == 0) {\r
-      break;\r
-    }\r
-\r
-    if ((AltStatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-    //\r
-    //  Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-    //\r
-    //  read Status Register will clear interrupt\r
-    //\r
-    StatusRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg.Status\r
-                      );\r
-\r
-    //\r
-    //  BSY==0,DRQ==1\r
-    //\r
-    if ((StatusRegister & (BSY | DRQ)) == DRQ) {\r
-      break;\r
-    }\r
-\r
-    if ((StatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   AltStatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-    //\r
-    //  read Status Register will clear interrupt\r
-    //\r
-    AltStatusRegister = ReadPortB (\r
-                          AtapiScsiPrivate->PciIo,\r
-                          AtapiScsiPrivate->IoPort->Alt.AltStatus\r
-                          );\r
-    //\r
-    //  BSY==0,DRQ==1\r
-    //\r
-    if ((AltStatusRegister & (BSY | DRQ)) == DRQ) {\r
-      break;\r
-    }\r
-\r
-    if ((AltStatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   StatusRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-\r
-    StatusRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg.Status\r
-                      );\r
-    if ((StatusRegister & BSY) == 0x00) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   AltStatusRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-\r
-    AltStatusRegister = ReadPortB (\r
-                          AtapiScsiPrivate->PciIo,\r
-                          AtapiScsiPrivate->IoPort->Alt.AltStatus\r
-                          );\r
-    if ((AltStatusRegister & BSY) == 0x00) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-    StatusRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg.Status\r
-                      );\r
-    //\r
-    //  BSY == 0 , DRDY == 1\r
-    //\r
-    if ((StatusRegister & (DRDY | BSY)) == DRDY) {\r
-      break;\r
-    }\r
-\r
-    if ((StatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT64  Delay;\r
-  UINT8   AltStatusRegister;\r
-  UINT8   ErrRegister;\r
-\r
-  if (TimeoutInMicroSeconds == 0) {\r
-    Delay = 2;\r
-  } else {\r
-    Delay = DivU64x32 (TimeoutInMicroSeconds, (UINT32) 30) + 1;\r
-  }\r
-\r
-  do {\r
-    AltStatusRegister = ReadPortB (\r
-                          AtapiScsiPrivate->PciIo,\r
-                          AtapiScsiPrivate->IoPort->Alt.AltStatus\r
-                          );\r
-    //\r
-    //  BSY == 0 , DRDY == 1\r
-    //\r
-    if ((AltStatusRegister & (DRDY | BSY)) == DRDY) {\r
-      break;\r
-    }\r
-\r
-    if ((AltStatusRegister & (BSY | ERR)) == ERR) {\r
-\r
-      ErrRegister = ReadPortB (\r
-                      AtapiScsiPrivate->PciIo,\r
-                      AtapiScsiPrivate->IoPort->Reg1.Error\r
-                      );\r
-      if ((ErrRegister & ABRT_ERR) == ABRT_ERR) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 30 us\r
-    //\r
-    gBS->Stall (30);\r
-    //\r
-    // Loop infinitely if not meeting expected condition\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      Delay = 2;\r
-    }\r
-\r
-    Delay--;\r
-  } while (Delay);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\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
-  UINT8 StatusRegister;\r
-  UINT8 ErrorRegister;\r
-\r
-  StatusRegister = ReadPortB (\r
-                    AtapiScsiPrivate->PciIo,\r
-                    AtapiScsiPrivate->IoPort->Reg.Status\r
-                    );\r
-\r
-  DEBUG_CODE_BEGIN ();\r
-\r
-    if (StatusRegister & DWF) {\r
-      DEBUG (\r
-        (EFI_D_BLKIO,\r
-        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",\r
-        StatusRegister)\r
-        );\r
-    }\r
-\r
-    if (StatusRegister & CORR) {\r
-      DEBUG (\r
-        (EFI_D_BLKIO,\r
-        "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
-        StatusRegister)\r
-        );\r
-    }\r
-\r
-    if (StatusRegister & ERR) {\r
-      ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);\r
-\r
-\r
-      if (ErrorRegister & BBK_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
-          ErrorRegister)\r
-          );\r
-      }\r
-\r
-      if (ErrorRegister & UNC_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
-          ErrorRegister)\r
-          );\r
-      }\r
-\r
-      if (ErrorRegister & MC_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",\r
-          ErrorRegister)\r
-          );\r
-      }\r
-\r
-      if (ErrorRegister & ABRT_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",\r
-          ErrorRegister)\r
-          );\r
-      }\r
-\r
-      if (ErrorRegister & TK0NF_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
-          ErrorRegister)\r
-          );\r
-      }\r
-\r
-      if (ErrorRegister & AMNF_ERR) {\r
-        DEBUG (\r
-          (EFI_D_BLKIO,\r
-          "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
-          ErrorRegister)\r
-          );\r
-       }\r
-    }\r
-\r
-  DEBUG_CODE_END ();\r
-\r
-  if ((StatusRegister & (ERR | DWF | CORR)) == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-\r
-  return EFI_DEVICE_ERROR;\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
-  EFI_STATUS                        Status;\r
-  EFI_SCSI_PASS_THRU_PROTOCOL       *ScsiPassThru;\r
-  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *ExtScsiPassThru;\r
-\r
-  ScsiPassThru = &AtapiScsiPrivate->ScsiPassThru;\r
-  ExtScsiPassThru = &AtapiScsiPrivate->ExtScsiPassThru;\r
-\r
-  if (FeaturePcdGet (PcdSupportScsiPassThru)) {\r
-    ScsiPassThru = CopyMem (ScsiPassThru, &gScsiPassThruProtocolTemplate, sizeof (*ScsiPassThru));\r
-    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {\r
-      ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      ControllerHandle,\r
-                      &gEfiScsiPassThruProtocolGuid,\r
-                      ScsiPassThru,\r
-                      &gEfiExtScsiPassThruProtocolGuid,\r
-                      ExtScsiPassThru,\r
-                      NULL\r
-                      );\r
-    } else {\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      ControllerHandle,\r
-                      &gEfiScsiPassThruProtocolGuid,\r
-                      ScsiPassThru,\r
-                      NULL\r
-                      );\r
-    }\r
-  } else {\r
-    if (FeaturePcdGet (PcdSupportExtScsiPassThru)) {\r
-      ExtScsiPassThru = CopyMem (ExtScsiPassThru, &gExtScsiPassThruProtocolTemplate, sizeof (*ExtScsiPassThru));\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      ControllerHandle,\r
-                      &gEfiExtScsiPassThruProtocolGuid,\r
-                      ExtScsiPassThru,\r
-                      NULL\r
-                      );\r
-    } else {\r
-      //\r
-      // This driver must support either ScsiPassThru or\r
-      // ExtScsiPassThru protocols\r
-      //\r
-      ASSERT (FALSE);\r
-      Status = EFI_UNSUPPORTED;\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  The user Entry Point for module AtapiPassThru. The user code starts with this function.\r
-\r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param[in] SystemTable    A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS       The entry point is executed successfully.\r
-  @retval other             Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeAtapiPassThru(\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  //\r
-  // Install driver model protocol(s).\r
-  //\r
-  Status = EfiLibInstallDriverBindingComponentName2 (\r
-             ImageHandle,\r
-             SystemTable,\r
-             &gAtapiScsiPassThruDriverBinding,\r
-             ImageHandle,\r
-             &gAtapiScsiPassThruComponentName,\r
-             &gAtapiScsiPassThruComponentName2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Install EFI Driver Supported EFI Version Protocol required for\r
-  // EFI drivers that are on PCI and other plug in cards.\r
-  //\r
-  gAtapiScsiPassThruDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &ImageHandle,\r
-                  &gEfiDriverSupportedEfiVersionProtocolGuid,\r
-                  &gAtapiScsiPassThruDriverSupportedEfiVersion,\r
-                  NULL\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r