]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / IdeBus.c
index e864eccc31005b757bcf6d644dbec378b7ed72e5..6648dfd541a91c6c3197828552c1886f62facd8a 100644 (file)
@@ -1,6 +1,10 @@
 /** @file\r
-  Copyright (c) 2006 - 2008, Intel Corporation\r
-  All rights reserved. This program and the accompanying materials\r
+  This file implement UEFI driver for IDE Bus which includes device identification,\r
+  Child device(Disk, CDROM, etc) enumeration and child handler installation, and\r
+  driver stop.\r
+\r
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  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
@@ -30,21 +34,106 @@ EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {
   NULL,\r
   NULL\r
 };\r
+/**\r
+  Deregister an IDE device and free resources\r
 \r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingSupported\r
-// ***********************************************************************************\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
+  @retval EFI_SUCCESS  Deregiter a specific IDE device successfully\r
+\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
+{\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
+  if (Index < MAX_IDE_DEVICE) {\r
+    IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
+  }\r
+  ReleaseIdeResources (IdeBlkIoDevice);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 /**\r
-  Register Driver Binding protocol for this driver.\r
+  Supported function of 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
+  @param This                A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param ControllerHandle    The handle of the controller to test.\r
+  @param 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
+  @retval  other       Driver not loaded.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -54,34 +143,46 @@ IDEBusDriverBindingSupported (
   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
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  PCI_TYPE00                        PciData;\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
+    // Check if RemainingDevicePath is the End of Device Path Node,\r
+    // if yes, go on checking other conditions\r
+    //\r
+    if (!IsDevicePathEnd (Node)) {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node,\r
+      // check its validation\r
+      //\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
   //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
+  // Verify the Ide Controller Init Protocol, which installed by the\r
+  // IdeController module.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\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
@@ -91,65 +192,94 @@ IDEBusDriverBindingSupported (
   }\r
 \r
   //\r
-  // Close protocol, don't use device path protocol in the .Support() function\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
   //\r
   gBS->CloseProtocol (\r
         Controller,\r
-        &gEfiDevicePathProtocolGuid,\r
+        &gEfiIdeControllerInitProtocolGuid,\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
+  // Open the EFI Device Path protocol needed to perform the supported test\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
-                  &gEfiIdeControllerInitProtocolGuid,\r
-                  (VOID **) &IdeInit,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\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
+  // Close protocol, don't use device path protocol in the Support() function\r
   //\r
   gBS->CloseProtocol (\r
         Controller,\r
-        &gEfiIdeControllerInitProtocolGuid,\r
+        &gEfiDevicePathProtocolGuid,\r
         This->DriverBindingHandle,\r
         Controller\r
         );\r
 \r
+  //\r
+  // Get the EfiPciIoProtocol\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
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Now further check the PCI header: Base class (offset 0x0B) and\r
+  // Sub Class (offset 0x0A). This controller should be an IDE controller\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        0,\r
+                        sizeof (PciData),\r
+                        &PciData\r
+                        );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Examine if it is IDE mode by class code\r
+    //\r
+    if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {\r
+      Status = EFI_UNSUPPORTED;\r
+    } else {\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStart\r
-// ***********************************************************************************\r
-//\r
+\r
 /**\r
-  Start this driver on Controller by detecting all disks and installing\r
-  BlockIo protocol on them.\r
+  Start function of Driver binding protocol which start this driver on Controller\r
+  by detecting all disks and installing 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
+  @param  This                Protocol instance pointer.\r
+  @param  Controller          Handle of device to bind driver to.\r
+  @param  RemainingDevicePath produce all possible children.\r
 \r
-  @retval  EFI_SUCCESS This driver is added to ControllerHandle.\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
+  @retval  other               This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -303,7 +433,7 @@ IDEBusDriverBindingStart (
                     &Supports\r
                     );\r
   if (!EFI_ERROR (Status)) {\r
-    Supports &= EFI_PCI_DEVICE_ENABLE;\r
+    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
     Status = PciIo->Attributes (\r
                       PciIo,\r
                       EfiPciIoAttributeOperationEnable,\r
@@ -332,34 +462,44 @@ IDEBusDriverBindingStart (
     ConfigurationOptions = 0x0f;\r
   }\r
 \r
-  if (EnumAll) {\r
+   if (EnumAll || RemainingDevicePath == NULL) {\r
     //\r
-    // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
+    // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,\r
+    // must enumerate all IDE devices 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
+  } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
     //\r
-    // RemainingDevicePath is not NULL, only scan the specified device.\r
+    // If RemainingDevicePath isn't the End of Device Path Node,\r
+    // only scan the specified device by RemainingDevicePath\r
     //\r
     Node                = (EFI_DEV_PATH *) RemainingDevicePath;\r
     BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
     EndIdeChannel       = BeginningIdeChannel;\r
     BeginningIdeDevice  = Node->Atapi.SlaveMaster;\r
     EndIdeDevice        = BeginningIdeDevice;\r
+    if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto ErrorExit;\r
+    }\r
+    if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto ErrorExit;\r
+    }\r
+\r
+  } else {\r
+    //\r
+    // If RemainingDevicePath is the End of Device Path Node,\r
+    // skip enumerate any device and return EFI_SUCESSS\r
+    //\r
+    BeginningIdeChannel = IdeMaxChannel;\r
+    EndIdeChannel       = IdeMaxChannel - 1;\r
+    BeginningIdeDevice  = IdeMaxDevice;\r
+    EndIdeDevice        = IdeMaxDevice - 1;\r
   }\r
 \r
   //\r
@@ -405,7 +545,7 @@ IDEBusDriverBindingStart (
     }\r
 \r
     EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
-\r
+    ASSERT (EndIdeDevice < IdeMaxDevice);\r
     //\r
     // Now inform the IDE Controller Init Module. Sept10\r
     //\r
@@ -517,9 +657,9 @@ IDEBusDriverBindingStart (
       //\r
       // Discover device, now!\r
       //\r
-      PERF_START (0, "DiscoverIdeDevice", "IDE", 0);\r
+      PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);\r
       Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
-      PERF_END (0, "DiscoverIdeDevice", "IDE", 0);\r
+      PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);\r
 \r
       IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;\r
       IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;\r
@@ -548,7 +688,7 @@ IDEBusDriverBindingStart (
         //\r
         // Submit identify data to IDE controller init driver\r
         //\r
-        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->pIdData, sizeof (IdentifyData));\r
+        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));\r
         IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
         IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
       } else {\r
@@ -579,6 +719,7 @@ IDEBusDriverBindingStart (
     //\r
     for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
 \r
+      ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);\r
       if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
         continue;\r
       }\r
@@ -598,12 +739,13 @@ IDEBusDriverBindingStart (
         continue;\r
       }\r
 \r
+      ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);\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
+      if (SupportedModes->PioMode.Mode <= AtaPioMode2) {\r
         TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
       } else {\r
         TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
@@ -664,9 +806,9 @@ IDEBusDriverBindingStart (
       //\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
+      DriveParameters.Sector          = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;\r
+      DriveParameters.Heads           = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);\r
+      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
       //\r
       // Set Parameters for the device:\r
       // 1) Init\r
@@ -690,7 +832,7 @@ IDEBusDriverBindingStart (
       // Add Component Name for the IDE/ATAPI device that was discovered.\r
       //\r
       IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
-      ADD_NAME (IdeBlkIoDevicePtr);\r
+      ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);\r
 \r
       Status = gBS->InstallMultipleProtocolInterfaces (\r
                       &IdeBlkIoDevicePtr->Handle,\r
@@ -730,11 +872,12 @@ IDEBusDriverBindingStart (
       //\r
       // Create event to clear pending IDE interrupt\r
       //\r
-      Status = gBS->CreateEvent (\r
-                      EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+      Status = gBS->CreateEventEx (\r
+                      EVT_NOTIFY_SIGNAL,\r
                       TPL_NOTIFY,\r
                       ClearInterrupt,\r
                       IdeBlkIoDevicePtr,\r
+                      &gEfiEventExitBootServicesGuid,\r
                       &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
                       );\r
 \r
@@ -754,11 +897,11 @@ IDEBusDriverBindingStart (
   IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
 \r
   if (SupportedModes != NULL) {\r
-    gBS->FreePool (SupportedModes);\r
+    FreePool (SupportedModes);\r
   }\r
 \r
-  PERF_START (0, "Finish IDE detection", "IDE", 1);\r
-  PERF_END (0, "Finish IDE detection", "IDE", 0);\r
+  PERF_START (NULL, "Finish IDE detection", "IDE", 1);\r
+  PERF_END (NULL, "Finish IDE detection", "IDE", 0);\r
 \r
   return EFI_SUCCESS;\r
 \r
@@ -812,14 +955,9 @@ ErrorExit:
   return Status;\r
 \r
 }\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBusDriverBindingStop\r
-// ***********************************************************************************\r
-//\r
 /**\r
-  Stop this driver on Controller Handle.\r
+  Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all\r
+  child handle attached to the controller handle if there are.\r
 \r
   @param  This Protocol instance pointer.\r
   @param  Controller Handle of device to stop driver on\r
@@ -838,8 +976,6 @@ IDEBusDriverBindingStop (
   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
@@ -868,7 +1004,7 @@ IDEBusDriverBindingStop (
                         &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
+        Supports &= (UINT64)(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
@@ -940,111 +1076,15 @@ IDEBusDriverBindingStop (
   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
+  issue ATA or ATAPI command to reset a block IO device.\r
+  @param  This                  Block IO protocol instance pointer.\r
+  @param  ExtendedVerification  If FALSE,for ATAPI device, driver will only invoke ATAPI reset method\r
+                                If TRUE, for ATAPI device, driver need invoke ATA reset method after\r
+                                invoke ATAPI reset method\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
+  @retval EFI_DEVICE_ERROR      When the device is neighther ATA device or ATAPI device.\r
+  @retval EFI_SUCCESS           The device reset successfully\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1094,15 +1134,16 @@ Done:
 }\r
 \r
 /**\r
-  Read data from block io device\r
+  Read data from a 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  This       Block IO 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
+  @param  Buffer     Caller supplied buffer to save data\r
 \r
-  @return read data status\r
+  @retval EFI_DEVICE_ERROR  unknown device type\r
+  @retval other             read data status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1110,11 +1151,10 @@ EFIAPI
 IDEBlkIoReadBlocks (\r
   IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
   IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 LBA,\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
@@ -1137,7 +1177,7 @@ IDEBlkIoReadBlocks (
     Status = AtaBlkIoReadBlocks (\r
             IdeBlkIoDevice,\r
             MediaId,\r
-            LBA,\r
+            Lba,\r
             BufferSize,\r
             Buffer\r
             );\r
@@ -1155,7 +1195,7 @@ IDEBlkIoReadBlocks (
   Status = AtapiBlkIoReadBlocks (\r
           IdeBlkIoDevice,\r
           MediaId,\r
-          LBA,\r
+          Lba,\r
           BufferSize,\r
           Buffer\r
           );\r
@@ -1167,15 +1207,16 @@ Done:
 }\r
 \r
 /**\r
-  Write data to block io device\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  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
+  @param  Buffer     Caller supplied buffer to save data\r
 \r
-  @return write data status\r
+  @retval EFI_DEVICE_ERROR  unknown device type\r
+  @retval other             write data status\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1183,11 +1224,10 @@ EFIAPI
 IDEBlkIoWriteBlocks (\r
   IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
   IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 LBA,\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
@@ -1210,7 +1250,7 @@ IDEBlkIoWriteBlocks (
     Status = AtaBlkIoWriteBlocks (\r
             IdeBlkIoDevice,\r
             MediaId,\r
-            LBA,\r
+            Lba,\r
             BufferSize,\r
             Buffer\r
             );\r
@@ -1228,7 +1268,7 @@ IDEBlkIoWriteBlocks (
   Status = AtapiBlkIoWriteBlocks (\r
           IdeBlkIoDevice,\r
           MediaId,\r
-          LBA,\r
+          Lba,\r
           BufferSize,\r
           Buffer\r
           );\r
@@ -1237,15 +1277,13 @@ Done:
   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
+  Flushes all modified data to a physical block devices\r
+\r
+  @param  This  Indicates a pointer to the calling context which to sepcify a\r
+                sepcific block device\r
+\r
+  @retval EFI_SUCCESS   Always return success.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1260,17 +1298,17 @@ IDEBlkIoFlushBlocks (
 }\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
+  This function is used by the IDE bus driver to get inquiry data.\r
+  Data format of Identify 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
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+  @param  InquiryData           Pointer to a buffer for the inquiry data.\r
+  @param  InquiryDataSize       Pointer to the value for the inquiry data size.\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
+  @retval EFI_SUCCESS           The command was accepted without any errors.\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
@@ -1290,28 +1328,28 @@ IDEDiskInfoInquiry (
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
-  if (IdeBlkIoDevice->pInquiryData == NULL) {\r
+  if (IdeBlkIoDevice->InquiryData == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  gBS->CopyMem (InquiryData, IdeBlkIoDevice->pInquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
+  gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, 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
+  This function is used by the IDE bus driver to get identify data.\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
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+  @param  IdentifyData          Pointer to a buffer for the identify data.\r
+  @param  IdentifyDataSize      Pointer to the value for the identify data size.\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
+  @retval EFI_SUCCESS           The command was accepted without any errors.\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
@@ -1331,29 +1369,29 @@ IDEDiskInfoIdentify (
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
-  if (IdeBlkIoDevice->pIdData == NULL) {\r
+  if (IdeBlkIoDevice->IdData == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  gBS->CopyMem (IdentifyData, IdeBlkIoDevice->pIdData, sizeof (EFI_IDENTIFY_DATA));\r
+  gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, 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
+  This function is used by the IDE bus driver to get sense data.\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
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+  @param  SenseData             Pointer to the SenseData.\r
+  @param  SenseDataSize         Size of SenseData in bytes.\r
+  @param  SenseDataNumber       Pointer to the value for the identify data size.\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
+  @retval EFI_SUCCESS           The command was accepted without any errors.\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
@@ -1369,15 +1407,14 @@ IDEDiskInfoSenseData (
 }\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
+  This function is used by the IDE bus driver to get controller information.\r
 \r
-  @param  This Protocol instance pointer.\r
-  @param  IdeChannel Primary or Secondary\r
-  @param  IdeDevice Master or Slave\r
+  @param  This                  Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
+  @param  IdeChannel            Pointer to the Ide Channel number. Primary or secondary.\r
+  @param  IdeDevice             Pointer to the Ide Device number. Master or slave.\r
 \r
-  @retval  EFI_SUCCESS IdeChannel and IdeDevice are valid\r
-  @retval  EFI_UNSUPPORTED This is not an IDE device\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
@@ -1397,12 +1434,109 @@ IDEDiskInfoWhichIde (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  The is an event(generally the event is exitBootService event) call back function.\r
+  Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
+\r
+  @param  Event   Pointer to this event\r
+  @param  Context Event handler private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT64          IoPortForBmis;\r
+  UINT8           RegisterValue;\r
+  IDE_BLK_IO_DEV  *IdeDev;\r
+\r
+  //\r
+  // Get our context\r
+  //\r
+  IdeDev = (IDE_BLK_IO_DEV *) Context;\r
+\r
+  //\r
+  // Obtain IDE IO port registers' base addresses\r
+  //\r
+  Status = ReassignIdeResources (IdeDev);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Check whether interrupt is pending\r
+  //\r
+\r
+  //\r
+  // Reset IDE device to force it de-assert interrupt pin\r
+  // Note: this will reset all devices on this IDE channel\r
+  //\r
+  Status = AtaSoftReset (IdeDev);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Get base address of IDE Bus Master Status Regsiter\r
+  //\r
+  if (IdePrimary == IdeDev->Channel) {\r
+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
+  } else {\r
+    if (IdeSecondary == IdeDev->Channel) {\r
+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
+    } else {\r
+      return;\r
+    }\r
+  }\r
+  //\r
+  // Read BMIS register and clear ERROR and INTR bit\r
+  //\r
+  IdeDev->PciIo->Io.Read (\r
+                      IdeDev->PciIo,\r
+                      EfiPciIoWidthUint8,\r
+                      EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                      IoPortForBmis,\r
+                      1,\r
+                      &RegisterValue\r
+                      );\r
+\r
+  RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
+\r
+  IdeDev->PciIo->Io.Write (\r
+                      IdeDev->PciIo,\r
+                      EfiPciIoWidthUint8,\r
+                      EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                      IoPortForBmis,\r
+                      1,\r
+                      &RegisterValue\r
+                      );\r
+\r
+  //\r
+  // Select the other device on this channel to ensure this device to release the interrupt pin\r
+  //\r
+  if (IdeDev->Device == 0) {\r
+    RegisterValue = (1 << 4) | 0xe0;\r
+  } else {\r
+    RegisterValue = (0 << 4) | 0xe0;\r
+  }\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    RegisterValue\r
+    );\r
+\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] ImageHandle    The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS       The entry point is executed successfully.\r
   @retval other             Some error occurs when executing this entry point.\r
 \r