]> git.proxmox.com Git - mirror_edk2.git/commitdiff
rename to meet naming rules
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 2 Jul 2008 03:25:36 +0000 (03:25 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 2 Jul 2008 03:25:36 +0000 (03:25 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5402 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Idebus.c [deleted file]

diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
new file mode 100644 (file)
index 0000000..666b817
--- /dev/null
@@ -0,0 +1,1436 @@
+/** @file\r
+  Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Revision Reference:\r
+  This module is modified from DXE\IDE module for Ide Contriller Init support\r
+\r
+**/\r
+\r
+#include "idebus.h"\r
+\r
+#define PCI_CLASS_MASS_STORAGE  0x01\r
+#define PCI_SUB_CLASS_IDE       0x01\r
+\r
+\r
+//\r
+// IDE Bus Driver Binding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
+  IDEBusDriverBindingSupported,\r
+  IDEBusDriverBindingStart,\r
+  IDEBusDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingSupported\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  Register Driver Binding protocol for this driver.\r
+\r
+  @param[in] This   -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in] ControllerHandle    -- The handle of the controller to test.\r
+  @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path.\r
+\r
+  @retval  EFI_SUCCESS Driver loaded.\r
+  @retval  other Driver not loaded.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+// TODO:    Controller - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
+  EFI_DEV_PATH                      *Node;\r
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
+\r
+  if (RemainingDevicePath != NULL) {\r
+    Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+    if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
+        Node->DevPath.SubType != MSG_ATAPI_DP ||\r
+        DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Close protocol, don't use device path protocol in the .Support() function\r
+  //\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiDevicePathProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+  //\r
+  // Verify the Ide Controller Init Protocol, which installed by the\r
+  // IdeController module.\r
+  // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
+  //         open BY_DRIVER here) That's why we don't check pciio protocol\r
+  // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
+  //         check here any more to save code size\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiIdeControllerInitProtocolGuid,\r
+                  (VOID **) &IdeInit,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // If protocols were opened normally, closed it\r
+  //\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiIdeControllerInitProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+  return Status;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingStart\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  Start this driver on Controller by detecting all disks and installing\r
+  BlockIo protocol on them.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  Controller Handle of device to bind driver to.\r
+  @param  RemainingDevicePath Not used, always produce all possible children.\r
+\r
+  @retval  EFI_SUCCESS This driver is added to ControllerHandle.\r
+  @retval  EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
+  @retval  other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_STATUS                        SavedStatus;\r
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
+  EFI_DEV_PATH                      *Node;\r
+  UINT8                             IdeChannel;\r
+  UINT8                             BeginningIdeChannel;\r
+  UINT8                             EndIdeChannel;\r
+  UINT8                             IdeDevice;\r
+  UINT8                             BeginningIdeDevice;\r
+  UINT8                             EndIdeDevice;\r
+  IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
+  IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;\r
+  IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];\r
+  ATA_TRANSFER_MODE                 TransferMode;\r
+  ATA_DRIVE_PARMS                   DriveParameters;\r
+  EFI_DEV_PATH                      NewNode;\r
+  UINT8                             ConfigurationOptions;\r
+  UINT16                            CommandBlockBaseAddr;\r
+  UINT16                            ControlBlockBaseAddr;\r
+  UINTN                             DataSize;\r
+  IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;\r
+  UINT64                            Supports;\r
+\r
+  //\r
+  // Local variables declaration for IdeControllerInit support\r
+  //\r
+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
+  BOOLEAN                           EnumAll;\r
+  BOOLEAN                           ChannelEnabled;\r
+  UINT8                             MaxDevices;\r
+  EFI_IDENTIFY_DATA                 IdentifyData;\r
+  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;\r
+\r
+  IdeBusDriverPrivateData = NULL;\r
+  SupportedModes          = NULL;\r
+\r
+  //\r
+  // Perform IdeBus initialization\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiIdeControllerInitProtocolGuid,\r
+                  (VOID **) &IdeInit,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+\r
+  //\r
+  // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
+  // will not return EFI_ALREADY_STARTED, so save it for now\r
+  //\r
+  SavedStatus = Status;\r
+\r
+  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+    DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
+    //\r
+    // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
+    //\r
+    goto ErrorExit;\r
+  }\r
+\r
+  //\r
+  // Save Enumall. Step7.2\r
+  //\r
+  EnumAll       = IdeInit->EnumAll;\r
+\r
+  //\r
+  // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
+  // attribute will not return EFI_ALREADY_STARTED\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
+    goto ErrorExit;\r
+  }\r
+\r
+  //\r
+  // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
+  //\r
+  if (SavedStatus != EFI_ALREADY_STARTED) {\r
+    IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+    if (IdeBusDriverPrivateData == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ErrorExit;\r
+    }\r
+\r
+    ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Controller,\r
+                    &gEfiCallerIdGuid,\r
+                    IdeBusDriverPrivateData,\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ErrorExit;\r
+    }\r
+\r
+  } else {\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiCallerIdGuid,\r
+                    (VOID **) &IdeBusDriverPrivateData,\r
+                    This->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      IdeBusDriverPrivateData = NULL;\r
+      goto ErrorExit;\r
+    }\r
+  }\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
+    Status = PciIo->Attributes (\r
+                      PciIo,\r
+                      EfiPciIoAttributeOperationEnable,\r
+                      Supports,\r
+                      NULL\r
+                      );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  //\r
+  // Read the environment variable that contains the IDEBus Driver's\r
+  // Config options that were set by the Driver Configuration Protocol\r
+  //\r
+  DataSize = sizeof (ConfigurationOptions);\r
+  Status = gRT->GetVariable (\r
+                  (CHAR16 *) L"Configuration",\r
+                  &gEfiCallerIdGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &ConfigurationOptions\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    ConfigurationOptions = 0x0f;\r
+  }\r
+\r
+  if (EnumAll) {\r
+    //\r
+    // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
+    //\r
+    BeginningIdeChannel = IdePrimary;\r
+    EndIdeChannel       = IdeSecondary;\r
+    BeginningIdeDevice  = IdeMaster;\r
+    EndIdeDevice        = IdeSlave;\r
+  } else if (RemainingDevicePath == NULL) {\r
+    //\r
+    // RemainingDevicePath is NULL, scan IDE bus for each device;\r
+    //\r
+    BeginningIdeChannel = IdePrimary;\r
+    EndIdeChannel       = IdeSecondary;\r
+    BeginningIdeDevice  = IdeMaster;\r
+    //\r
+    // default, may be redefined by IdeInit\r
+    //\r
+    EndIdeDevice = IdeSlave;\r
+  } else {\r
+    //\r
+    // RemainingDevicePath is not NULL, only scan the specified device.\r
+    //\r
+    Node                = (EFI_DEV_PATH *) RemainingDevicePath;\r
+    BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
+    EndIdeChannel       = BeginningIdeChannel;\r
+    BeginningIdeDevice  = Node->Atapi.SlaveMaster;\r
+    EndIdeDevice        = BeginningIdeDevice;\r
+  }\r
+\r
+  //\r
+  // Obtain IDE IO port registers' base addresses\r
+  //\r
+  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  //\r
+  // Report status code: begin IdeBus initialization\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+    ParentDevicePath\r
+    );\r
+\r
+  //\r
+  // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
+  //\r
+  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
+\r
+    //\r
+    // now obtain channel information fron IdeControllerInit protocol. Step9\r
+    //\r
+    Status = IdeInit->GetChannelInfo (\r
+                        IdeInit,\r
+                        IdeChannel,\r
+                        &ChannelEnabled,\r
+                        &MaxDevices\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
+      continue;\r
+    }\r
+\r
+    if (!ChannelEnabled) {\r
+      continue;\r
+    }\r
+\r
+    EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
+\r
+    //\r
+    // Now inform the IDE Controller Init Module. Sept10\r
+    //\r
+    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
+\r
+    //\r
+    // No reset channel function implemented. Sept11\r
+    //\r
+    IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
+\r
+    //\r
+    // Step13\r
+    //\r
+    IdeInit->NotifyPhase (\r
+              IdeInit,\r
+              EfiIdeBusBeforeDevicePresenceDetection,\r
+              IdeChannel\r
+              );\r
+\r
+    //\r
+    // Prepare to detect IDE device of this channel\r
+    //\r
+    InitializeIDEChannelData ();\r
+\r
+    //\r
+    // -- 1st inner loop --- Master/Slave ------------  Step14\r
+    //\r
+    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+      //\r
+      // Check whether the configuration options allow this device\r
+      //\r
+      if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // The device has been scanned in another Start(), No need to scan it again\r
+      // for perf optimization.\r
+      //\r
+      if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // create child handle for the detected device.\r
+      //\r
+      IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
+      if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
+        continue;\r
+      }\r
+\r
+      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+      ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
+\r
+      IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;\r
+      IdeBlkIoDevicePtr->Channel    = (EFI_IDE_CHANNEL) IdeChannel;\r
+      IdeBlkIoDevicePtr->Device     = (EFI_IDE_DEVICE) IdeDevice;\r
+\r
+      //\r
+      // initialize Block IO interface's Media pointer\r
+      //\r
+      IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
+\r
+      //\r
+      // Initialize IDE IO port addresses, including Command Block registers\r
+      // and Control Block registers\r
+      //\r
+      IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
+      if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
+        continue;\r
+      }\r
+\r
+      ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
+      CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
+      ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
+\r
+      IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
+      IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
+      IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
+      IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
+      IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
+      IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+\r
+      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
+      IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
+\r
+      IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
+\r
+      IdeBlkIoDevicePtr->PciIo = PciIo;\r
+      IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
+      IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
+\r
+      //\r
+      // Report Status code: is about to detect IDE drive\r
+      //\r
+      REPORT_STATUS_CODE_EX (\r
+        EFI_PROGRESS_CODE,\r
+        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
+        0,\r
+        &gEfiCallerIdGuid,\r
+        NULL,\r
+        NULL,\r
+        0\r
+      );\r
+\r
+      //\r
+      // Discover device, now!\r
+      //\r
+      PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
+      Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
+      PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
+\r
+      IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;\r
+      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Set Device Path\r
+        //\r
+        ZeroMem (&NewNode, sizeof (NewNode));\r
+        NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;\r
+        NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
+        SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
+\r
+        NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;\r
+        NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;\r
+        NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;\r
+        IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
+                                          ParentDevicePath,\r
+                                          &NewNode.DevPath\r
+                                          );\r
+        if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
+          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Submit identify data to IDE controller init driver\r
+        //\r
+        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
+        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
+        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
+      } else {\r
+        //\r
+        // Device detection failed\r
+        //\r
+        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
+        ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+        IdeBlkIoDevicePtr = NULL;\r
+      }\r
+      //\r
+      // end of 1st inner loop ---\r
+      //\r
+    }\r
+    //\r
+    // end of 1st outer loop =========\r
+    //\r
+  }\r
+\r
+  //\r
+  // = 2nd outer loop == Primary/Secondary =================\r
+  //\r
+  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+    //\r
+    // -- 2nd inner loop --- Master/Slave --------\r
+    //\r
+    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+\r
+      if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
+        continue;\r
+      }\r
+\r
+      if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
+        continue;\r
+      }\r
+\r
+      Status = IdeInit->CalculateMode (\r
+                          IdeInit,\r
+                          IdeChannel,\r
+                          IdeDevice,\r
+                          &SupportedModes\r
+                          );\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
+        continue;\r
+      }\r
+\r
+      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+      //\r
+      // Set best supported PIO mode on this IDE device\r
+      //\r
+      if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
+      } else {\r
+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
+      }\r
+\r
+      TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
+\r
+      if (SupportedModes->ExtModeCount == 0){\r
+        Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+          IdeBlkIoDevicePtr = NULL;\r
+          continue;\r
+        }\r
+      }\r
+\r
+      //\r
+      // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
+      // be set together. Only one DMA mode can be set to a device. If setting\r
+      // DMA mode operation fails, we can continue moving on because we only use\r
+      // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
+      //\r
+      if (SupportedModes->UdmaMode.Valid) {\r
+\r
+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
+        TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);\r
+        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+          IdeBlkIoDevicePtr = NULL;\r
+          continue;\r
+        }\r
+        //\r
+        // Record Udma Mode\r
+        //\r
+        IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
+        IdeBlkIoDevicePtr->UdmaMode.Mode  = SupportedModes->UdmaMode.Mode;\r
+        EnableInterrupt (IdeBlkIoDevicePtr);\r
+      } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
+\r
+        TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
+        TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
+        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+          IdeBlkIoDevicePtr = NULL;\r
+          continue;\r
+        }\r
+\r
+        EnableInterrupt (IdeBlkIoDevicePtr);\r
+      }\r
+      //\r
+      // Init driver parameters\r
+      //\r
+      DriveParameters.Sector          = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
+      DriveParameters.Heads           = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
+      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
+      //\r
+      // Set Parameters for the device:\r
+      // 1) Init\r
+      // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
+      //\r
+      if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
+        Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
+      }\r
+\r
+      //\r
+      // Record PIO mode used in private data\r
+      //\r
+      IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
+\r
+      //\r
+      // Set IDE controller Timing Blocks in the PCI Configuration Space\r
+      //\r
+      IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
+\r
+      //\r
+      // Add Component Name for the IDE/ATAPI device that was discovered.\r
+      //\r
+      IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
+      ADD_NAME (IdeBlkIoDevicePtr);\r
+\r
+      Status = gBS->InstallMultipleProtocolInterfaces (\r
+                      &IdeBlkIoDevicePtr->Handle,\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      IdeBlkIoDevicePtr->DevicePath,\r
+                      &gEfiBlockIoProtocolGuid,\r
+                      &IdeBlkIoDevicePtr->BlkIo,\r
+                      &gEfiDiskInfoProtocolGuid,\r
+                      &IdeBlkIoDevicePtr->DiskInfo,\r
+                      NULL\r
+                      );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+      }\r
+\r
+      gBS->OpenProtocol (\r
+            Controller,\r
+            &gEfiPciIoProtocolGuid,\r
+            (VOID **) &PciIo,\r
+            This->DriverBindingHandle,\r
+            IdeBlkIoDevicePtr->Handle,\r
+            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+            );\r
+\r
+      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
+\r
+      //\r
+      // Report status code: device eanbled!\r
+      //\r
+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+        EFI_PROGRESS_CODE,\r
+        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
+        IdeBlkIoDevicePtr->DevicePath\r
+        );\r
+\r
+      //\r
+      // Create event to clear pending IDE interrupt\r
+      //\r
+      Status = gBS->CreateEvent (\r
+                      EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                      TPL_NOTIFY,\r
+                      ClearInterrupt,\r
+                      IdeBlkIoDevicePtr,\r
+                      &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
+                      );\r
+\r
+      //\r
+      // end of 2nd inner loop ----\r
+      //\r
+    }\r
+    //\r
+    // end of 2nd outer loop ==========\r
+    //\r
+  }\r
+\r
+  //\r
+  // All configurations done! Notify IdeController to do post initialization\r
+  // work such as saving IDE controller PCI settings for S3 resume\r
+  //\r
+  IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
+\r
+  if (SupportedModes != NULL) {\r
+    gBS->FreePool (SupportedModes);\r
+  }\r
+\r
+  PERF_START (0, "Finish IDE detection", "IDE", 1);\r
+  PERF_END (0, "Finish IDE detection", "IDE", 0);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+\r
+  //\r
+  // Report error code: controller error\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
+    ParentDevicePath\r
+    );\r
+\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiIdeControllerInitProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+        Controller,\r
+        &gEfiCallerIdGuid,\r
+        IdeBusDriverPrivateData,\r
+        NULL\r
+        );\r
+\r
+  if (IdeBusDriverPrivateData != NULL) {\r
+    gBS->FreePool (IdeBusDriverPrivateData);\r
+  }\r
+\r
+  if (SupportedModes != NULL) {\r
+    gBS->FreePool (SupportedModes);\r
+  }\r
+\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiPciIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiDevicePathProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBusDriverBindingStop\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  Stop this driver on Controller Handle.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  DeviceHandle Handle of device to stop driver on\r
+  @param  NumberOfChildren Not used\r
+  @param  ChildHandleBuffer Not used\r
+\r
+  @retval  EFI_SUCCESS This driver is removed DeviceHandle\r
+  @retval  other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Controller,\r
+  IN  UINTN                           NumberOfChildren,\r
+  IN  EFI_HANDLE                      *ChildHandleBuffer\r
+  )\r
+// TODO:    Controller - add argument and description to function comment\r
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_PCI_IO_PROTOCOL         *PciIo;\r
+  BOOLEAN                     AllChildrenStopped;\r
+  UINTN                       Index;\r
+  IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+  UINT64                      Supports;\r
+\r
+  IdeBusDriverPrivateData = NULL;\r
+\r
+  if (NumberOfChildren == 0) {\r
+\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiPciIoProtocolGuid,\r
+                    (VOID **) &PciIo,\r
+                    This->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = PciIo->Attributes (\r
+                        PciIo,\r
+                        EfiPciIoAttributeOperationSupported,\r
+                        0,\r
+                        &Supports\r
+                        );\r
+      if (!EFI_ERROR (Status)) {\r
+        Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
+        PciIo->Attributes (\r
+                PciIo,\r
+                EfiPciIoAttributeOperationDisable,\r
+                Supports,\r
+                NULL\r
+                );\r
+      }\r
+    }\r
+\r
+    gBS->OpenProtocol (\r
+          Controller,\r
+          &gEfiCallerIdGuid,\r
+          (VOID **) &IdeBusDriverPrivateData,\r
+          This->DriverBindingHandle,\r
+          Controller,\r
+          EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+          );\r
+\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+          Controller,\r
+          &gEfiCallerIdGuid,\r
+          IdeBusDriverPrivateData,\r
+          NULL\r
+          );\r
+\r
+    if (IdeBusDriverPrivateData != NULL) {\r
+      gBS->FreePool (IdeBusDriverPrivateData);\r
+    }\r
+    //\r
+    // Close the bus driver\r
+    //\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiIdeControllerInitProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiPciIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiDevicePathProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  AllChildrenStopped = TRUE;\r
+\r
+  for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+    Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      AllChildrenStopped = FALSE;\r
+    }\r
+  }\r
+\r
+  if (!AllChildrenStopped) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// DeRegisterIdeDevice\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  Deregister an IDE device and free resources\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  Controller Ide device handle\r
+  @param  Handle Handle of device to deregister driver on\r
+\r
+  @return EFI_STATUS\r
+\r
+**/\r
+EFI_STATUS\r
+DeRegisterIdeDevice (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN  EFI_HANDLE                     Controller,\r
+  IN  EFI_HANDLE                     Handle\r
+  )\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
+  IDE_BLK_IO_DEV        *IdeBlkIoDevice;\r
+  EFI_PCI_IO_PROTOCOL   *PciIo;\r
+  UINTN                 Index;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  (VOID **) &BlkIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
+\r
+  //\r
+  // Report Status code: Device disabled\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
+    IdeBlkIoDevice->DevicePath\r
+    );\r
+\r
+  //\r
+  // Close the child handle\r
+  //\r
+  Status = gBS->CloseProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  This->DriverBindingHandle,\r
+                  Handle\r
+                  );\r
+\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  Handle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  IdeBlkIoDevice->DevicePath,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  &IdeBlkIoDevice->BlkIo,\r
+                  &gEfiDiskInfoProtocolGuid,\r
+                  &IdeBlkIoDevice->DiskInfo,\r
+                  NULL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->OpenProtocol (\r
+          Controller,\r
+          &gEfiPciIoProtocolGuid,\r
+          (VOID **) &PciIo,\r
+          This->DriverBindingHandle,\r
+          Handle,\r
+          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+          );\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Release allocated resources\r
+  //\r
+  Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
+  IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
+\r
+  ReleaseIdeResources (IdeBlkIoDevice);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBlkIoReset\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  TODO:    This - add argument and description to function comment\r
+  TODO:    ExtendedVerification - add argument and description to function comment\r
+  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReset (\r
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
+  IN  BOOLEAN                 ExtendedVerification\r
+  )\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+  EFI_STATUS      Status;\r
+  EFI_TPL         OldTpl;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+  //\r
+  // Requery IDE IO resources in case of the switch of native and legacy modes\r
+  //\r
+  ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+  //\r
+  // for ATA device, using ATA reset method\r
+  //\r
+  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+    Status = AtaSoftReset (IdeBlkIoDevice);\r
+    goto Done;\r
+  }\r
+\r
+  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // for ATAPI device, using ATAPI reset method\r
+  //\r
+  Status = AtapiSoftReset (IdeBlkIoDevice);\r
+  if (ExtendedVerification) {\r
+    Status = AtaSoftReset (IdeBlkIoDevice);\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read data from block io device\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  MediaId The media ID of the device\r
+  @param  LBA Starting LBA address to read data\r
+  @param  BufferSize The size of data to be read\r
+  @param  Buffer Caller supplied buffer to save data\r
+\r
+  @return read data status\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReadBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
+  IN  UINT32                  MediaId,\r
+  IN  EFI_LBA                 LBA,\r
+  IN  UINTN                   BufferSize,\r
+  OUT VOID                    *Buffer\r
+  )\r
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+  EFI_STATUS      Status;\r
+  EFI_TPL         OldTpl;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Requery IDE IO resources in case of the switch of native and legacy modes\r
+  //\r
+  ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+  //\r
+  // For ATA compatible device, use ATA read block's mechanism\r
+  //\r
+  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+    Status = AtaBlkIoReadBlocks (\r
+            IdeBlkIoDevice,\r
+            MediaId,\r
+            LBA,\r
+            BufferSize,\r
+            Buffer\r
+            );\r
+    goto Done;\r
+  }\r
+\r
+  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // for ATAPI device, using ATAPI read block's mechanism\r
+  //\r
+  Status = AtapiBlkIoReadBlocks (\r
+          IdeBlkIoDevice,\r
+          MediaId,\r
+          LBA,\r
+          BufferSize,\r
+          Buffer\r
+          );\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Write data to block io device\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  MediaId The media ID of the device\r
+  @param  LBA Starting LBA address to write data\r
+  @param  BufferSize The size of data to be written\r
+  @param  Buffer Caller supplied buffer to save data\r
+\r
+  @return write data status\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoWriteBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
+  IN  UINT32                  MediaId,\r
+  IN  EFI_LBA                 LBA,\r
+  IN  UINTN                   BufferSize,\r
+  IN  VOID                    *Buffer\r
+  )\r
+// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+  EFI_STATUS      Status;\r
+  EFI_TPL         OldTpl;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+  //\r
+  // Requery IDE IO resources in case of the switch of native and legacy modes\r
+  //\r
+  ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+  //\r
+  // for ATA device, using ATA write block's mechanism\r
+  //\r
+  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+\r
+    Status = AtaBlkIoWriteBlocks (\r
+            IdeBlkIoDevice,\r
+            MediaId,\r
+            LBA,\r
+            BufferSize,\r
+            Buffer\r
+            );\r
+    goto Done;\r
+  }\r
+\r
+  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // for ATAPI device, using ATAPI write block's mechanism\r
+  //\r
+  Status = AtapiBlkIoWriteBlocks (\r
+          IdeBlkIoDevice,\r
+          MediaId,\r
+          LBA,\r
+          BufferSize,\r
+          Buffer\r
+          );\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+//\r
+// ***********************************************************************************\r
+// IDEBlkIoFlushBlocks\r
+// ***********************************************************************************\r
+//\r
+/**\r
+  TODO:    This - add argument and description to function comment\r
+  TODO:    EFI_SUCCESS - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoFlushBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL   *This\r
+  )\r
+{\r
+  //\r
+  // return directly\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Return the results of the Inquiry command to a drive in InquiryData.\r
+  Data format of Inquiry data is defined by the Interface GUID.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  InquiryData Results of Inquiry command to device\r
+  @param  InquiryDataSize Size of InquiryData in bytes.\r
+\r
+  @retval  EFI_SUCCESS InquiryData valid\r
+  @retval  EFI_NOT_FOUND Device does not support this data class\r
+  @retval  EFI_DEVICE_ERROR Error reading InquiryData from device\r
+  @retval  EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoInquiry (\r
+  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
+  IN OUT VOID                     *InquiryData,\r
+  IN OUT UINT32                   *InquiryDataSize\r
+  )\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+  if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
+    *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  if (IdeBlkIoDevice->pInquiryData == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
+  *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Return the results of the Identify command to a drive in IdentifyData.\r
+  Data format of Identify data is defined by the Interface GUID.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  IdentifyData Results of Identify command to device\r
+  @param  IdentifyDataSize Size of IdentifyData in bytes.\r
+\r
+  @retval  EFI_SUCCESS IdentifyData valid\r
+  @retval  EFI_NOT_FOUND Device does not support this data class\r
+  @retval  EFI_DEVICE_ERROR Error reading IdentifyData from device\r
+  @retval  EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoIdentify (\r
+  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
+  IN OUT VOID                     *IdentifyData,\r
+  IN OUT UINT32                   *IdentifyDataSize\r
+  )\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+\r
+  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+  if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
+    *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  if (IdeBlkIoDevice->pIdData == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
+  *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Return the results of the Request Sense command to a drive in SenseData.\r
+  Data format of Sense data is defined by the Interface GUID.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  SenseData Results of Request Sense command to device\r
+  @param  SenseDataSize Size of SenseData in bytes.\r
+  @param  SenseDataNumber Type of SenseData\r
+\r
+  @retval  EFI_SUCCESS InquiryData valid\r
+  @retval  EFI_NOT_FOUND Device does not support this data class\r
+  @retval  EFI_DEVICE_ERROR Error reading InquiryData from device\r
+  @retval  EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoSenseData (\r
+  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
+  IN OUT VOID                     *SenseData,\r
+  IN OUT UINT32                   *SenseDataSize,\r
+  OUT    UINT8                    *SenseDataNumber\r
+  )\r
+{\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Return the results of the Request Sense command to a drive in SenseData.\r
+  Data format of Sense data is defined by the Interface GUID.\r
+\r
+  @param  This Protocol instance pointer.\r
+  @param  IdeChannel Primary or Secondary\r
+  @param  IdeDevice Master or Slave\r
+\r
+  @retval  EFI_SUCCESS IdeChannel and IdeDevice are valid\r
+  @retval  EFI_UNSUPPORTED This is not an IDE device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoWhichIde (\r
+  IN  EFI_DISK_INFO_PROTOCOL   *This,\r
+  OUT UINT32                   *IdeChannel,\r
+  OUT UINT32                   *IdeDevice\r
+  )\r
+{\r
+  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
+\r
+  IdeBlkIoDevice  = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+  *IdeChannel     = IdeBlkIoDevice->Channel;\r
+  *IdeDevice      = IdeBlkIoDevice->Device;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The user Entry Point for module IdeBus. 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
+InitializeIdeBus(\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 = EfiLibInstallAllDriverProtocols2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gIDEBusDriverBinding,\r
+             ImageHandle,\r
+             &gIDEBusComponentName,\r
+             &gIDEBusComponentName2,\r
+             NULL,\r
+             &gIDEBusDriverDiagnostics,\r
+             &gIDEBusDriverDiagnostics2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Idebus.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Idebus.c
deleted file mode 100644 (file)
index 666b817..0000000
+++ /dev/null
@@ -1,1436 +0,0 @@
-/** @file\r
-  Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
-  All rights reserved. This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-  @par Revision Reference:\r
-  This module is modified from DXE\IDE module for Ide Contriller Init support\r
-\r
-**/\r
-\r
-#include "idebus.h"\r
-\r
-#define PCI_CLASS_MASS_STORAGE  0x01\r
-#define PCI_SUB_CLASS_IDE       0x01\r
-\r
-\r
-//\r
-// IDE Bus Driver Binding Protocol Instance\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
-  IDEBusDriverBindingSupported,\r
-  IDEBusDriverBindingStart,\r
-  IDEBusDriverBindingStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingSupported\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  Register Driver Binding protocol for this driver.\r
-\r
-  @param[in] This   -- A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
-  @param[in] ControllerHandle    -- The handle of the controller to test.\r
-  @param[in] RemainingDevicePath -- A pointer to the remaining portion of a device path.\r
-\r
-  @retval  EFI_SUCCESS Driver loaded.\r
-  @retval  other Driver not loaded.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-// TODO:    Controller - add argument and description to function comment\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
-  EFI_DEV_PATH                      *Node;\r
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
-\r
-  if (RemainingDevicePath != NULL) {\r
-    Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
-    if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
-        Node->DevPath.SubType != MSG_ATAPI_DP ||\r
-        DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Close protocol, don't use device path protocol in the .Support() function\r
-  //\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiDevicePathProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  //\r
-  // Verify the Ide Controller Init Protocol, which installed by the\r
-  // IdeController module.\r
-  // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
-  //         open BY_DRIVER here) That's why we don't check pciio protocol\r
-  // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
-  //         check here any more to save code size\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIdeControllerInitProtocolGuid,\r
-                  (VOID **) &IdeInit,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // If protocols were opened normally, closed it\r
-  //\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiIdeControllerInitProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  return Status;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStart\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  Start this driver on Controller by detecting all disks and installing\r
-  BlockIo protocol on them.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  Controller Handle of device to bind driver to.\r
-  @param  RemainingDevicePath Not used, always produce all possible children.\r
-\r
-  @retval  EFI_SUCCESS This driver is added to ControllerHandle.\r
-  @retval  EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
-  @retval  other This driver does not support this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_STATUS                        SavedStatus;\r
-  EFI_PCI_IO_PROTOCOL               *PciIo;\r
-  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
-  EFI_DEV_PATH                      *Node;\r
-  UINT8                             IdeChannel;\r
-  UINT8                             BeginningIdeChannel;\r
-  UINT8                             EndIdeChannel;\r
-  UINT8                             IdeDevice;\r
-  UINT8                             BeginningIdeDevice;\r
-  UINT8                             EndIdeDevice;\r
-  IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
-  IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;\r
-  IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];\r
-  ATA_TRANSFER_MODE                 TransferMode;\r
-  ATA_DRIVE_PARMS                   DriveParameters;\r
-  EFI_DEV_PATH                      NewNode;\r
-  UINT8                             ConfigurationOptions;\r
-  UINT16                            CommandBlockBaseAddr;\r
-  UINT16                            ControlBlockBaseAddr;\r
-  UINTN                             DataSize;\r
-  IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;\r
-  UINT64                            Supports;\r
-\r
-  //\r
-  // Local variables declaration for IdeControllerInit support\r
-  //\r
-  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
-  BOOLEAN                           EnumAll;\r
-  BOOLEAN                           ChannelEnabled;\r
-  UINT8                             MaxDevices;\r
-  EFI_IDENTIFY_DATA                 IdentifyData;\r
-  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;\r
-\r
-  IdeBusDriverPrivateData = NULL;\r
-  SupportedModes          = NULL;\r
-\r
-  //\r
-  // Perform IdeBus initialization\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIdeControllerInitProtocolGuid,\r
-                  (VOID **) &IdeInit,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  //\r
-  // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
-  // will not return EFI_ALREADY_STARTED, so save it for now\r
-  //\r
-  SavedStatus = Status;\r
-\r
-  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
-    DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
-    //\r
-    // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
-    //\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Save Enumall. Step7.2\r
-  //\r
-  EnumAll       = IdeInit->EnumAll;\r
-\r
-  //\r
-  // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
-  // attribute will not return EFI_ALREADY_STARTED\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
-  //\r
-  if (SavedStatus != EFI_ALREADY_STARTED) {\r
-    IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
-    if (IdeBusDriverPrivateData == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto ErrorExit;\r
-    }\r
-\r
-    ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
-    Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &Controller,\r
-                    &gEfiCallerIdGuid,\r
-                    IdeBusDriverPrivateData,\r
-                    NULL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      goto ErrorExit;\r
-    }\r
-\r
-  } else {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiCallerIdGuid,\r
-                    (VOID **) &IdeBusDriverPrivateData,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      IdeBusDriverPrivateData = NULL;\r
-      goto ErrorExit;\r
-    }\r
-  }\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
-    Status = PciIo->Attributes (\r
-                      PciIo,\r
-                      EfiPciIoAttributeOperationEnable,\r
-                      Supports,\r
-                      NULL\r
-                      );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Read the environment variable that contains the IDEBus Driver's\r
-  // Config options that were set by the Driver Configuration Protocol\r
-  //\r
-  DataSize = sizeof (ConfigurationOptions);\r
-  Status = gRT->GetVariable (\r
-                  (CHAR16 *) L"Configuration",\r
-                  &gEfiCallerIdGuid,\r
-                  NULL,\r
-                  &DataSize,\r
-                  &ConfigurationOptions\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    ConfigurationOptions = 0x0f;\r
-  }\r
-\r
-  if (EnumAll) {\r
-    //\r
-    // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
-    //\r
-    BeginningIdeChannel = IdePrimary;\r
-    EndIdeChannel       = IdeSecondary;\r
-    BeginningIdeDevice  = IdeMaster;\r
-    EndIdeDevice        = IdeSlave;\r
-  } else if (RemainingDevicePath == NULL) {\r
-    //\r
-    // RemainingDevicePath is NULL, scan IDE bus for each device;\r
-    //\r
-    BeginningIdeChannel = IdePrimary;\r
-    EndIdeChannel       = IdeSecondary;\r
-    BeginningIdeDevice  = IdeMaster;\r
-    //\r
-    // default, may be redefined by IdeInit\r
-    //\r
-    EndIdeDevice = IdeSlave;\r
-  } else {\r
-    //\r
-    // RemainingDevicePath is not NULL, only scan the specified device.\r
-    //\r
-    Node                = (EFI_DEV_PATH *) RemainingDevicePath;\r
-    BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
-    EndIdeChannel       = BeginningIdeChannel;\r
-    BeginningIdeDevice  = Node->Atapi.SlaveMaster;\r
-    EndIdeDevice        = BeginningIdeDevice;\r
-  }\r
-\r
-  //\r
-  // Obtain IDE IO port registers' base addresses\r
-  //\r
-  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
-  if (EFI_ERROR (Status)) {\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Report status code: begin IdeBus initialization\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
-    ParentDevicePath\r
-    );\r
-\r
-  //\r
-  // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
-  //\r
-  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
-\r
-    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
-\r
-    //\r
-    // now obtain channel information fron IdeControllerInit protocol. Step9\r
-    //\r
-    Status = IdeInit->GetChannelInfo (\r
-                        IdeInit,\r
-                        IdeChannel,\r
-                        &ChannelEnabled,\r
-                        &MaxDevices\r
-                        );\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
-      continue;\r
-    }\r
-\r
-    if (!ChannelEnabled) {\r
-      continue;\r
-    }\r
-\r
-    EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
-\r
-    //\r
-    // Now inform the IDE Controller Init Module. Sept10\r
-    //\r
-    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
-\r
-    //\r
-    // No reset channel function implemented. Sept11\r
-    //\r
-    IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
-\r
-    //\r
-    // Step13\r
-    //\r
-    IdeInit->NotifyPhase (\r
-              IdeInit,\r
-              EfiIdeBusBeforeDevicePresenceDetection,\r
-              IdeChannel\r
-              );\r
-\r
-    //\r
-    // Prepare to detect IDE device of this channel\r
-    //\r
-    InitializeIDEChannelData ();\r
-\r
-    //\r
-    // -- 1st inner loop --- Master/Slave ------------  Step14\r
-    //\r
-    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
-      //\r
-      // Check whether the configuration options allow this device\r
-      //\r
-      if (!(ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice)))) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // The device has been scanned in another Start(), No need to scan it again\r
-      // for perf optimization.\r
-      //\r
-      if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // create child handle for the detected device.\r
-      //\r
-      IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
-      if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
-        continue;\r
-      }\r
-\r
-      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
-\r
-      ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
-\r
-      IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;\r
-      IdeBlkIoDevicePtr->Channel    = (EFI_IDE_CHANNEL) IdeChannel;\r
-      IdeBlkIoDevicePtr->Device     = (EFI_IDE_DEVICE) IdeDevice;\r
-\r
-      //\r
-      // initialize Block IO interface's Media pointer\r
-      //\r
-      IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
-\r
-      //\r
-      // Initialize IDE IO port addresses, including Command Block registers\r
-      // and Control Block registers\r
-      //\r
-      IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
-      if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
-        continue;\r
-      }\r
-\r
-      ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
-      CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
-      ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
-\r
-      IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
-      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
-      IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
-      IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
-      IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
-      IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
-      IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
-      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
-\r
-      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
-      IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
-\r
-      IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
-\r
-      IdeBlkIoDevicePtr->PciIo = PciIo;\r
-      IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
-      IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
-\r
-      //\r
-      // Report Status code: is about to detect IDE drive\r
-      //\r
-      REPORT_STATUS_CODE_EX (\r
-        EFI_PROGRESS_CODE,\r
-        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
-        0,\r
-        &gEfiCallerIdGuid,\r
-        NULL,\r
-        NULL,\r
-        0\r
-      );\r
-\r
-      //\r
-      // Discover device, now!\r
-      //\r
-      PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
-      Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
-      PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
-\r
-      IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;\r
-      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;\r
-\r
-      if (!EFI_ERROR (Status)) {\r
-        //\r
-        // Set Device Path\r
-        //\r
-        ZeroMem (&NewNode, sizeof (NewNode));\r
-        NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;\r
-        NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
-        SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
-\r
-        NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;\r
-        NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;\r
-        NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;\r
-        IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
-                                          ParentDevicePath,\r
-                                          &NewNode.DevPath\r
-                                          );\r
-        if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
-          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-          continue;\r
-        }\r
-\r
-        //\r
-        // Submit identify data to IDE controller init driver\r
-        //\r
-        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
-        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
-        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
-      } else {\r
-        //\r
-        // Device detection failed\r
-        //\r
-        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
-        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
-        ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-        IdeBlkIoDevicePtr = NULL;\r
-      }\r
-      //\r
-      // end of 1st inner loop ---\r
-      //\r
-    }\r
-    //\r
-    // end of 1st outer loop =========\r
-    //\r
-  }\r
-\r
-  //\r
-  // = 2nd outer loop == Primary/Secondary =================\r
-  //\r
-  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
-\r
-    //\r
-    // -- 2nd inner loop --- Master/Slave --------\r
-    //\r
-    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
-\r
-      if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
-        continue;\r
-      }\r
-\r
-      if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
-        continue;\r
-      }\r
-\r
-      Status = IdeInit->CalculateMode (\r
-                          IdeInit,\r
-                          IdeChannel,\r
-                          IdeDevice,\r
-                          &SupportedModes\r
-                          );\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
-        continue;\r
-      }\r
-\r
-      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
-\r
-      //\r
-      // Set best supported PIO mode on this IDE device\r
-      //\r
-      if (SupportedModes->PioMode.Mode <= ATA_PIO_MODE_2) {\r
-        TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
-      } else {\r
-        TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
-      }\r
-\r
-      TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
-\r
-      if (SupportedModes->ExtModeCount == 0){\r
-        Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
-        if (EFI_ERROR (Status)) {\r
-          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
-          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-          IdeBlkIoDevicePtr = NULL;\r
-          continue;\r
-        }\r
-      }\r
-\r
-      //\r
-      // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
-      // be set together. Only one DMA mode can be set to a device. If setting\r
-      // DMA mode operation fails, we can continue moving on because we only use\r
-      // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
-      //\r
-      if (SupportedModes->UdmaMode.Valid) {\r
-\r
-        TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
-        TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);\r
-        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
-        if (EFI_ERROR (Status)) {\r
-          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
-          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-          IdeBlkIoDevicePtr = NULL;\r
-          continue;\r
-        }\r
-        //\r
-        // Record Udma Mode\r
-        //\r
-        IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
-        IdeBlkIoDevicePtr->UdmaMode.Mode  = SupportedModes->UdmaMode.Mode;\r
-        EnableInterrupt (IdeBlkIoDevicePtr);\r
-      } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
-\r
-        TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
-        TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
-        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
-\r
-        if (EFI_ERROR (Status)) {\r
-          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
-          ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-          IdeBlkIoDevicePtr = NULL;\r
-          continue;\r
-        }\r
-\r
-        EnableInterrupt (IdeBlkIoDevicePtr);\r
-      }\r
-      //\r
-      // Init driver parameters\r
-      //\r
-      DriveParameters.Sector          = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.sectors_per_track;\r
-      DriveParameters.Heads           = (UINT8) (IdeBlkIoDevicePtr->pIdData->AtaData.heads - 1);\r
-      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->pIdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
-      //\r
-      // Set Parameters for the device:\r
-      // 1) Init\r
-      // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
-      //\r
-      if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
-        Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
-      }\r
-\r
-      //\r
-      // Record PIO mode used in private data\r
-      //\r
-      IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
-\r
-      //\r
-      // Set IDE controller Timing Blocks in the PCI Configuration Space\r
-      //\r
-      IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
-\r
-      //\r
-      // Add Component Name for the IDE/ATAPI device that was discovered.\r
-      //\r
-      IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
-      ADD_NAME (IdeBlkIoDevicePtr);\r
-\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &IdeBlkIoDevicePtr->Handle,\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      IdeBlkIoDevicePtr->DevicePath,\r
-                      &gEfiBlockIoProtocolGuid,\r
-                      &IdeBlkIoDevicePtr->BlkIo,\r
-                      &gEfiDiskInfoProtocolGuid,\r
-                      &IdeBlkIoDevicePtr->DiskInfo,\r
-                      NULL\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        ReleaseIdeResources (IdeBlkIoDevicePtr);\r
-      }\r
-\r
-      gBS->OpenProtocol (\r
-            Controller,\r
-            &gEfiPciIoProtocolGuid,\r
-            (VOID **) &PciIo,\r
-            This->DriverBindingHandle,\r
-            IdeBlkIoDevicePtr->Handle,\r
-            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-            );\r
-\r
-      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
-\r
-      //\r
-      // Report status code: device eanbled!\r
-      //\r
-      REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-        EFI_PROGRESS_CODE,\r
-        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
-        IdeBlkIoDevicePtr->DevicePath\r
-        );\r
-\r
-      //\r
-      // Create event to clear pending IDE interrupt\r
-      //\r
-      Status = gBS->CreateEvent (\r
-                      EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
-                      TPL_NOTIFY,\r
-                      ClearInterrupt,\r
-                      IdeBlkIoDevicePtr,\r
-                      &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
-                      );\r
-\r
-      //\r
-      // end of 2nd inner loop ----\r
-      //\r
-    }\r
-    //\r
-    // end of 2nd outer loop ==========\r
-    //\r
-  }\r
-\r
-  //\r
-  // All configurations done! Notify IdeController to do post initialization\r
-  // work such as saving IDE controller PCI settings for S3 resume\r
-  //\r
-  IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
-\r
-  if (SupportedModes != NULL) {\r
-    gBS->FreePool (SupportedModes);\r
-  }\r
-\r
-  PERF_START (0, "Finish IDE detection", "IDE", 1);\r
-  PERF_END (0, "Finish IDE detection", "IDE", 0);\r
-\r
-  return EFI_SUCCESS;\r
-\r
-ErrorExit:\r
-\r
-  //\r
-  // Report error code: controller error\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
-    ParentDevicePath\r
-    );\r
-\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiIdeControllerInitProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  gBS->UninstallMultipleProtocolInterfaces (\r
-        Controller,\r
-        &gEfiCallerIdGuid,\r
-        IdeBusDriverPrivateData,\r
-        NULL\r
-        );\r
-\r
-  if (IdeBusDriverPrivateData != NULL) {\r
-    gBS->FreePool (IdeBusDriverPrivateData);\r
-  }\r
-\r
-  if (SupportedModes != NULL) {\r
-    gBS->FreePool (SupportedModes);\r
-  }\r
-\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiPciIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiDevicePathProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  return Status;\r
-\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStop\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  Stop this driver on Controller Handle.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  DeviceHandle Handle of device to stop driver on\r
-  @param  NumberOfChildren Not used\r
-  @param  ChildHandleBuffer Not used\r
-\r
-  @retval  EFI_SUCCESS This driver is removed DeviceHandle\r
-  @retval  other This driver was not removed from this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
-  IN  EFI_HANDLE                      Controller,\r
-  IN  UINTN                           NumberOfChildren,\r
-  IN  EFI_HANDLE                      *ChildHandleBuffer\r
-  )\r
-// TODO:    Controller - add argument and description to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_PCI_IO_PROTOCOL         *PciIo;\r
-  BOOLEAN                     AllChildrenStopped;\r
-  UINTN                       Index;\r
-  IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
-  UINT64                      Supports;\r
-\r
-  IdeBusDriverPrivateData = NULL;\r
-\r
-  if (NumberOfChildren == 0) {\r
-\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiPciIoProtocolGuid,\r
-                    (VOID **) &PciIo,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      Status = PciIo->Attributes (\r
-                        PciIo,\r
-                        EfiPciIoAttributeOperationSupported,\r
-                        0,\r
-                        &Supports\r
-                        );\r
-      if (!EFI_ERROR (Status)) {\r
-        Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
-        PciIo->Attributes (\r
-                PciIo,\r
-                EfiPciIoAttributeOperationDisable,\r
-                Supports,\r
-                NULL\r
-                );\r
-      }\r
-    }\r
-\r
-    gBS->OpenProtocol (\r
-          Controller,\r
-          &gEfiCallerIdGuid,\r
-          (VOID **) &IdeBusDriverPrivateData,\r
-          This->DriverBindingHandle,\r
-          Controller,\r
-          EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-          );\r
-\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-          Controller,\r
-          &gEfiCallerIdGuid,\r
-          IdeBusDriverPrivateData,\r
-          NULL\r
-          );\r
-\r
-    if (IdeBusDriverPrivateData != NULL) {\r
-      gBS->FreePool (IdeBusDriverPrivateData);\r
-    }\r
-    //\r
-    // Close the bus driver\r
-    //\r
-    gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiIdeControllerInitProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
-    gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
-    gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiDevicePathProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  AllChildrenStopped = TRUE;\r
-\r
-  for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
-    Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      AllChildrenStopped = FALSE;\r
-    }\r
-  }\r
-\r
-  if (!AllChildrenStopped) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// DeRegisterIdeDevice\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  Deregister an IDE device and free resources\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  Controller Ide device handle\r
-  @param  Handle Handle of device to deregister driver on\r
-\r
-  @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-DeRegisterIdeDevice (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  EFI_HANDLE                     Handle\r
-  )\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  EFI_STATUS            Status;\r
-  EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
-  IDE_BLK_IO_DEV        *IdeBlkIoDevice;\r
-  EFI_PCI_IO_PROTOCOL   *PciIo;\r
-  UINTN                 Index;\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiBlockIoProtocolGuid,\r
-                  (VOID **) &BlkIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
-\r
-  //\r
-  // Report Status code: Device disabled\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
-    IdeBlkIoDevice->DevicePath\r
-    );\r
-\r
-  //\r
-  // Close the child handle\r
-  //\r
-  Status = gBS->CloseProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  This->DriverBindingHandle,\r
-                  Handle\r
-                  );\r
-\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  IdeBlkIoDevice->DevicePath,\r
-                  &gEfiBlockIoProtocolGuid,\r
-                  &IdeBlkIoDevice->BlkIo,\r
-                  &gEfiDiskInfoProtocolGuid,\r
-                  &IdeBlkIoDevice->DiskInfo,\r
-                  NULL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->OpenProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          (VOID **) &PciIo,\r
-          This->DriverBindingHandle,\r
-          Handle,\r
-          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-          );\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Release allocated resources\r
-  //\r
-  Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
-  IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
-\r
-  ReleaseIdeResources (IdeBlkIoDevice);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBlkIoReset\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  TODO:    This - add argument and description to function comment\r
-  TODO:    ExtendedVerification - add argument and description to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReset (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  BOOLEAN                 ExtendedVerification\r
-  )\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-  EFI_STATUS      Status;\r
-  EFI_TPL         OldTpl;\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
-  //\r
-  // Requery IDE IO resources in case of the switch of native and legacy modes\r
-  //\r
-  ReassignIdeResources (IdeBlkIoDevice);\r
-\r
-  //\r
-  // for ATA device, using ATA reset method\r
-  //\r
-  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
-      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
-    Status = AtaSoftReset (IdeBlkIoDevice);\r
-    goto Done;\r
-  }\r
-\r
-  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // for ATAPI device, using ATAPI reset method\r
-  //\r
-  Status = AtapiSoftReset (IdeBlkIoDevice);\r
-  if (ExtendedVerification) {\r
-    Status = AtaSoftReset (IdeBlkIoDevice);\r
-  }\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Read data from block io device\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  MediaId The media ID of the device\r
-  @param  LBA Starting LBA address to read data\r
-  @param  BufferSize The size of data to be read\r
-  @param  Buffer Caller supplied buffer to save data\r
-\r
-  @return read data status\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoReadBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 LBA,\r
-  IN  UINTN                   BufferSize,\r
-  OUT VOID                    *Buffer\r
-  )\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-  EFI_STATUS      Status;\r
-  EFI_TPL         OldTpl;\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Requery IDE IO resources in case of the switch of native and legacy modes\r
-  //\r
-  ReassignIdeResources (IdeBlkIoDevice);\r
-\r
-  //\r
-  // For ATA compatible device, use ATA read block's mechanism\r
-  //\r
-  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
-      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
-    Status = AtaBlkIoReadBlocks (\r
-            IdeBlkIoDevice,\r
-            MediaId,\r
-            LBA,\r
-            BufferSize,\r
-            Buffer\r
-            );\r
-    goto Done;\r
-  }\r
-\r
-  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // for ATAPI device, using ATAPI read block's mechanism\r
-  //\r
-  Status = AtapiBlkIoReadBlocks (\r
-          IdeBlkIoDevice,\r
-          MediaId,\r
-          LBA,\r
-          BufferSize,\r
-          Buffer\r
-          );\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Write data to block io device\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  MediaId The media ID of the device\r
-  @param  LBA Starting LBA address to write data\r
-  @param  BufferSize The size of data to be written\r
-  @param  Buffer Caller supplied buffer to save data\r
-\r
-  @return write data status\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoWriteBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 LBA,\r
-  IN  UINTN                   BufferSize,\r
-  IN  VOID                    *Buffer\r
-  )\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-  EFI_STATUS      Status;\r
-  EFI_TPL         OldTpl;\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
-  //\r
-  // Requery IDE IO resources in case of the switch of native and legacy modes\r
-  //\r
-  ReassignIdeResources (IdeBlkIoDevice);\r
-\r
-  //\r
-  // for ATA device, using ATA write block's mechanism\r
-  //\r
-  if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
-      IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
-\r
-    Status = AtaBlkIoWriteBlocks (\r
-            IdeBlkIoDevice,\r
-            MediaId,\r
-            LBA,\r
-            BufferSize,\r
-            Buffer\r
-            );\r
-    goto Done;\r
-  }\r
-\r
-  if (IdeBlkIoDevice->Type == IdeUnknown) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // for ATAPI device, using ATAPI write block's mechanism\r
-  //\r
-  Status = AtapiBlkIoWriteBlocks (\r
-          IdeBlkIoDevice,\r
-          MediaId,\r
-          LBA,\r
-          BufferSize,\r
-          Buffer\r
-          );\r
-\r
-Done:\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBlkIoFlushBlocks\r
-// ***********************************************************************************\r
-//\r
-/**\r
-  TODO:    This - add argument and description to function comment\r
-  TODO:    EFI_SUCCESS - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBlkIoFlushBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This\r
-  )\r
-{\r
-  //\r
-  // return directly\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Return the results of the Inquiry command to a drive in InquiryData.\r
-  Data format of Inquiry data is defined by the Interface GUID.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  InquiryData Results of Inquiry command to device\r
-  @param  InquiryDataSize Size of InquiryData in bytes.\r
-\r
-  @retval  EFI_SUCCESS InquiryData valid\r
-  @retval  EFI_NOT_FOUND Device does not support this data class\r
-  @retval  EFI_DEVICE_ERROR Error reading InquiryData from device\r
-  @retval  EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoInquiry (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *InquiryData,\r
-  IN OUT UINT32                   *InquiryDataSize\r
-  )\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
-\r
-  if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
-    *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  if (IdeBlkIoDevice->pInquiryData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
-  *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Return the results of the Identify command to a drive in IdentifyData.\r
-  Data format of Identify data is defined by the Interface GUID.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  IdentifyData Results of Identify command to device\r
-  @param  IdentifyDataSize Size of IdentifyData in bytes.\r
-\r
-  @retval  EFI_SUCCESS IdentifyData valid\r
-  @retval  EFI_NOT_FOUND Device does not support this data class\r
-  @retval  EFI_DEVICE_ERROR Error reading IdentifyData from device\r
-  @retval  EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoIdentify (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *IdentifyData,\r
-  IN OUT UINT32                   *IdentifyDataSize\r
-  )\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-\r
-  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
-\r
-  if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
-    *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  if (IdeBlkIoDevice->pIdData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
-  *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Return the results of the Request Sense command to a drive in SenseData.\r
-  Data format of Sense data is defined by the Interface GUID.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  SenseData Results of Request Sense command to device\r
-  @param  SenseDataSize Size of SenseData in bytes.\r
-  @param  SenseDataNumber Type of SenseData\r
-\r
-  @retval  EFI_SUCCESS InquiryData valid\r
-  @retval  EFI_NOT_FOUND Device does not support this data class\r
-  @retval  EFI_DEVICE_ERROR Error reading InquiryData from device\r
-  @retval  EFI_BUFFER_TOO_SMALL SenseDataSize not big enough\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoSenseData (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *SenseData,\r
-  IN OUT UINT32                   *SenseDataSize,\r
-  OUT    UINT8                    *SenseDataNumber\r
-  )\r
-{\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
-  Return the results of the Request Sense command to a drive in SenseData.\r
-  Data format of Sense data is defined by the Interface GUID.\r
-\r
-  @param  This Protocol instance pointer.\r
-  @param  IdeChannel Primary or Secondary\r
-  @param  IdeDevice Master or Slave\r
-\r
-  @retval  EFI_SUCCESS IdeChannel and IdeDevice are valid\r
-  @retval  EFI_UNSUPPORTED This is not an IDE device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEDiskInfoWhichIde (\r
-  IN  EFI_DISK_INFO_PROTOCOL   *This,\r
-  OUT UINT32                   *IdeChannel,\r
-  OUT UINT32                   *IdeDevice\r
-  )\r
-{\r
-  IDE_BLK_IO_DEV  *IdeBlkIoDevice;\r
-\r
-  IdeBlkIoDevice  = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
-  *IdeChannel     = IdeBlkIoDevice->Channel;\r
-  *IdeDevice      = IdeBlkIoDevice->Device;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  The user Entry Point for module IdeBus. 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
-InitializeIdeBus(\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 = EfiLibInstallAllDriverProtocols2 (\r
-             ImageHandle,\r
-             SystemTable,\r
-             &gIDEBusDriverBinding,\r
-             ImageHandle,\r
-             &gIDEBusComponentName,\r
-             &gIDEBusComponentName2,\r
-             NULL,\r
-             &gIDEBusDriverDiagnostics,\r
-             &gIDEBusDriverDiagnostics2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r