]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Code scrub for IdeBusDxe driver
authorjchen20 <jchen20@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 24 Jun 2009 02:21:05 +0000 (02:21 +0000)
committerjchen20 <jchen20@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 24 Jun 2009 02:21:05 +0000 (02:21 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8636 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Ata.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ComponentName.h
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverConfiguration.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/DriverDiagnostics.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Ide.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Ide.h
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.c
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBus.h

index 87d466f9d07c8340952c8a446951e00113b8251b..98d9323ea7541612053318e63f23bb36eb5ebe7a 100644 (file)
@@ -1,4 +1,6 @@
 /** @file\r
+  This file contains all helper functions on the ATA command \r
+  \r
   Copyright (c) 2006 - 2008, 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
 **/\r
 \r
 #include "IdeBus.h"\r
+/**\r
+  This function is called by ATAIdentify() to identity whether this disk\r
+  supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
+\r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                all the information of the IDE device.\r
+\r
+  @retval EFI_SUCCESS       The disk specified by IdeDev is a Atapi6 supported one and \r
+                            48-bit addressing must be used\r
+  @retval EFI_UNSUPPORTED   The disk dosn't not support Atapi6 or it supports but the \r
+                            capacity is below 120G, 48bit addressing is not needed\r
+  @retval  EFI_DEVICE_ERROR      The identify data in IdeDev is incorrect\r
+  @retval  EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.\r
+\r
+  @note  This function must be called after DEVICE_IDENTITY command has been\r
+          successfully returned\r
+\r
+**/\r
+EFI_STATUS\r
+AtaAtapi6Identify (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev\r
+  )\r
+{\r
+  UINT8             Index;\r
+  EFI_LBA           TmpLba;\r
+  EFI_LBA           Capacity;\r
+  EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;\r
+\r
+  if (IdeDev->IdData == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Atapi6IdentifyStruct = IdeDev->IdData;\r
+\r
+  if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & (BIT15 | BIT14)) != 0x4000) {\r
+    //\r
+    // Per ATA-6 spec, word83: bit15 is zero and bit14 is one\r
+    //\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {\r
+    //\r
+    // The device dosn't support 48 bit addressing\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // 48 bit address feature set is supported, get maximum capacity\r
+  //\r
+  Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];\r
+  for (Index = 1; Index < 4; Index++) {\r
+    //\r
+    // Lower byte goes first: word[100] is the lowest word, word[103] is highest\r
+    //\r
+    TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];\r
+    Capacity |= LShiftU64 (TmpLba, 16 * Index);\r
+  }\r
+\r
+  if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {\r
+    //\r
+    // Capacity exceeds 120GB. 48-bit addressing is really needed\r
+    //\r
+    IdeDev->Type = Ide48bitAddressingHardDisk;\r
+\r
+    //\r
+    // Fill block media information:Media->LogicalPartition ,\r
+    // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.\r
+    //\r
+    IdeDev->BlkIo.Media->IoAlign        = 4;\r
+    IdeDev->BlkIo.Media->MediaId        = 1;\r
+    IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
+    IdeDev->BlkIo.Media->MediaPresent   = TRUE;\r
+    IdeDev->BlkIo.Media->ReadOnly       = FALSE;\r
+    IdeDev->BlkIo.Media->BlockSize      = 0x200;\r
+    IdeDev->BlkIo.Media->LastBlock      = Capacity - 1;\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_UNSUPPORTED;\r
+}\r
+/**\r
+  Enable SMART of the disk if supported\r
+\r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record \r
+                all the information of the IDE device.\r
+**/\r
+VOID\r
+AtaSMARTSupport (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  BOOLEAN           SMARTSupported;\r
+  UINT8             Device;\r
+  EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;\r
+  UINT8             DeviceSelect;\r
+  UINT8             LBAMid;\r
+  UINT8             LBAHigh;\r
+\r
+  //\r
+  // Detect if the device supports S.M.A.R.T.\r
+  //\r
+  if ((IdeDev->IdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {\r
+    //\r
+    // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)\r
+    //\r
+    return ;\r
+  } else {\r
+    if ((IdeDev->IdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {\r
+      //\r
+      // S.M.A.R.T is not supported by the device\r
+      //\r
+      SMARTSupported = FALSE;\r
+    } else {\r
+      SMARTSupported = TRUE;\r
+    }\r
+  }\r
+\r
+  if (!SMARTSupported) {\r
+    //\r
+    // Report nonsupport status code\r
+    //\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)\r
+      );\r
+  } else {\r
+    //\r
+    // Enable this feature\r
+    //\r
+    REPORT_STATUS_CODE (\r
+      EFI_PROGRESS_CODE,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)\r
+      );\r
+\r
+    Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
+    Status = AtaNonDataCommandIn (\r
+              IdeDev,\r
+              ATA_CMD_SMART,\r
+              Device,\r
+              ATA_SMART_ENABLE_OPERATION,\r
+              0,\r
+              0,\r
+              ATA_CONSTANT_4F,\r
+              ATA_CONSTANT_C2\r
+              );\r
+    //\r
+    // Detect if this feature is enabled\r
+    //\r
+    TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
+    if (TmpAtaIdentifyPointer == NULL) {\r
+      return;\r
+    }\r
+\r
+    DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);\r
+    Status = AtaPioDataIn (\r
+              IdeDev,\r
+              (VOID *) TmpAtaIdentifyPointer,\r
+              sizeof (EFI_IDENTIFY_DATA),\r
+              ATA_CMD_IDENTIFY_DRIVE,\r
+              DeviceSelect,\r
+              0,\r
+              0,\r
+              0,\r
+              0\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePool (TmpAtaIdentifyPointer);\r
+      return ;\r
+    }\r
+\r
+    //\r
+    // Check if the feature is enabled\r
+    //\r
+    if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {\r
+      //\r
+      // Read status data\r
+      //\r
+      AtaNonDataCommandIn (\r
+        IdeDev,\r
+        ATA_CMD_SMART,\r
+        Device,\r
+        ATA_SMART_RETURN_STATUS,\r
+        0,\r
+        0,\r
+        ATA_CONSTANT_4F,\r
+        ATA_CONSTANT_C2\r
+        );\r
+      LBAMid  = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
+      LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);\r
+\r
+      if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {\r
+        //\r
+        // The threshold exceeded condition is not detected by the device\r
+        //\r
+        REPORT_STATUS_CODE (\r
+              EFI_PROGRESS_CODE,\r
+              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)\r
+              );\r
 \r
+      } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {\r
+        //\r
+        // The threshold exceeded condition is  detected by the device\r
+        //\r
+        REPORT_STATUS_CODE (\r
+              EFI_PROGRESS_CODE,\r
+              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)\r
+              );\r
+      }\r
+\r
+    } else {\r
+      //\r
+      // Report disabled status code\r
+      //\r
+      REPORT_STATUS_CODE (\r
+            EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+            (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)\r
+            );\r
+    }\r
+\r
+    gBS->FreePool (TmpAtaIdentifyPointer);\r
+  }\r
+\r
+  return ;\r
+}\r
 /**\r
   Sends out an ATA Identify Command to the specified device.\r
 \r
   information it needs to fill the IDE_BLK_IO_DEV data structure,\r
   including device type, media block size, media capacity, and etc.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure,used\r
-  to record all the information of the IDE device.\r
-\r
-  @retval EFI_SUCCESS Identify ATA device successfully.\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure,used to record \r
+                 all the information of the IDE device.\r
 \r
-  @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or\r
-  device is not ATA device.\r
-\r
-  @note\r
-  parameter IdeDev will be updated in this function.\r
+  @retval EFI_SUCCESS      Identify ATA device successfully.\r
+  @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.\r
+  @note  parameter IdeDev will be updated in this function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -178,153 +402,71 @@ ATAIdentify (
   return EFI_DEVICE_ERROR;\r
 }\r
 \r
-\r
 /**\r
-  This function is called by ATAIdentify() to identity whether this disk\r
-  supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @retval  EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one\r
-  and 48-bit addressing must be used\r
-\r
-  @retval  EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but\r
-  the capacity is below 120G, 48bit addressing is not needed\r
+  This function is a helper function used to change the char order in a string. It\r
+  is designed specially for the PrintAtaModuleName() function. After the IDE device \r
+  is detected, the IDE driver gets the device module name by sending ATA command \r
+  called ATA Identify Command or ATAPI Identify Command to the specified IDE device.\r
+  The module name returned is a string of ASCII characters: the first character is bit8--bit15\r
+  of the first word, the second character is BIT0--bit7 of the first word and so on. Thus\r
+  the string can not be print directly before it is preprocessed by this func to change \r
+  the order of characters in each word in the string.\r
+\r
+  @param Destination Indicates the destination string.\r
+  @param Source      Indicates the source string.\r
+  @param Size         the length of the string\r
+**/\r
+VOID\r
+SwapStringChars (\r
+  IN CHAR8  *Destination,\r
+  IN CHAR8  *Source,\r
+  IN UINT32 Size\r
+  )\r
+{\r
+  UINT32  Index;\r
+  CHAR8   Temp;\r
 \r
-  @retval  EFI_DEVICE_ERROR The identify data in IdeDev is incorrect\r
-  \r
-  @retval  EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.\r
+  for (Index = 0; Index < Size; Index += 2) {\r
 \r
-  @note\r
-  This function must be called after DEVICE_IDENTITY command has been\r
-  successfully returned\r
+    Temp                    = Source[Index + 1];\r
+    Destination[Index + 1]  = Source[Index];\r
+    Destination[Index]      = Temp;\r
+  }\r
+}\r
+/**\r
+  This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.\r
 \r
+  @param  IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                   all the information of the IDE device.\r
 **/\r
-EFI_STATUS\r
-AtaAtapi6Identify (\r
+VOID\r
+PrintAtaModuleName (\r
   IN  IDE_BLK_IO_DEV  *IdeDev\r
   )\r
 {\r
-  UINT8             Index;\r
-  EFI_LBA           TmpLba;\r
-  EFI_LBA           Capacity;\r
-  EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;\r
-\r
   if (IdeDev->IdData == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+    return ;\r
   }\r
 \r
-  Atapi6IdentifyStruct = IdeDev->IdData;\r
+  SwapStringChars (IdeDev->ModelName, IdeDev->IdData->AtaData.ModelName, 40);\r
+  IdeDev->ModelName[40] = 0x00;\r
+}\r
 \r
-  if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & (BIT15 | BIT14)) != 0x4000) {\r
-    //\r
-    // Per ATA-6 spec, word83: bit15 is zero and bit14 is one\r
-    //\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & BIT10) == 0) {\r
-    //\r
-    // The device dosn't support 48 bit addressing\r
-    //\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // 48 bit address feature set is supported, get maximum capacity\r
-  //\r
-  Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];\r
-  for (Index = 1; Index < 4; Index++) {\r
-    //\r
-    // Lower byte goes first: word[100] is the lowest word, word[103] is highest\r
-    //\r
-    TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];\r
-    Capacity |= LShiftU64 (TmpLba, 16 * Index);\r
-  }\r
-\r
-  if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {\r
-    //\r
-    // Capacity exceeds 120GB. 48-bit addressing is really needed\r
-    //\r
-    IdeDev->Type = Ide48bitAddressingHardDisk;\r
-\r
-    //\r
-    // Fill block media information:Media->LogicalPartition ,\r
-    // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.\r
-    //\r
-    IdeDev->BlkIo.Media->IoAlign        = 4;\r
-    IdeDev->BlkIo.Media->MediaId        = 1;\r
-    IdeDev->BlkIo.Media->RemovableMedia = FALSE;\r
-    IdeDev->BlkIo.Media->MediaPresent   = TRUE;\r
-    IdeDev->BlkIo.Media->ReadOnly       = FALSE;\r
-    IdeDev->BlkIo.Media->BlockSize      = 0x200;\r
-    IdeDev->BlkIo.Media->LastBlock      = Capacity - 1;\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
-  This function is called by ATAIdentify() or ATAPIIdentify()\r
-  to print device's module name.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-**/\r
-VOID\r
-PrintAtaModuleName (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  )\r
-{\r
-  if (IdeDev->IdData == NULL) {\r
-    return ;\r
-  }\r
-\r
-  SwapStringChars (IdeDev->ModelName, IdeDev->IdData->AtaData.ModelName, 40);\r
-  IdeDev->ModelName[40] = 0x00;\r
-}\r
-\r
-/**\r
-  This function is used to send out ATA commands conforms to the\r
-  PIO Data In Protocol.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *Buffer\r
-  buffer contained data transferred from device to host.\r
-\r
-  @param[in] ByteCount\r
-  data size in byte unit of the buffer.\r
-\r
-  @param[in] AtaCommand\r
-  value of the Command Register\r
-\r
-  @param[in] Head\r
-  value of the Head/Device Register\r
-\r
-  @param[in] SectorCount\r
-  value of the Sector Count Register\r
-\r
-  @param[in] SectorNumber\r
-  value of the Sector Number Register\r
-\r
-  @param[in] CylinderLsb\r
-  value of the low byte of the Cylinder Register\r
-\r
-  @param[in] CylinderMsb\r
-  value of the high byte of the Cylinder Register\r
-\r
-  @retval EFI_SUCCESS send out the ATA command and device send required\r
-  data successfully.\r
+/**\r
+  This function is used to send out ATA commands conforms to the PIO Data In Protocol.\r
 \r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                      all the information of the IDE device.\r
+  @param Buffer       buffer contained data transferred from device to host.\r
+  @param ByteCount    data size in byte unit of the buffer.\r
+  @param AtaCommand   value of the Command Register\r
+  @param Head         value of the Head/Device Register\r
+  @param SectorCount  value of the Sector Count Register\r
+  @param SectorNumber value of the Sector Number Register\r
+  @param CylinderLsb  value of the low byte of the Cylinder Register\r
+  @param CylinderMsb  value of the high byte of the Cylinder Register\r
+  \r
+  @retval EFI_SUCCESS      send out the ATA command and device send required data successfully.\r
   @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
@@ -461,10 +603,8 @@ AtaPioDataIn (
   This function is used to send out ATA commands conforms to the\r
   PIO Data Out Protocol.\r
 \r
-  @param *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
   @param *Buffer      buffer contained data transferred from host to device.\r
   @param ByteCount    data size in byte unit of the buffer.\r
   @param AtaCommand   value of the Command Register\r
@@ -474,9 +614,8 @@ AtaPioDataIn (
   @param CylinderLsb  value of the low byte of the Cylinder Register\r
   @param CylinderMsb  value of the high byte of the Cylinder Register\r
 \r
-  @retval EFI_SUCCESS send out the ATA command and device received required\r
-  data successfully.\r
-\r
+  @retval EFI_SUCCESS      send out the ATA command and device received required\r
+                           data successfully.\r
   @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
@@ -613,9 +752,8 @@ AtaPioDataOut (
   some debug information and if there is ERR bit set in the Status\r
   Register, the Error Register's value is also be parsed and print out.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure, used to \r
+                 record all the information of the IDE device.\r
 \r
   @retval EFI_SUCCESS       No err information in the Status Register.\r
   @retval EFI_DEVICE_ERROR  Any err information in the Status Register.\r
@@ -633,26 +771,26 @@ CheckErrorStatus (
 \r
   DEBUG_CODE_BEGIN ();\r
 \r
-    if ((StatusRegister & ATA_STSREG_DWF) != 0) {\r
-      DEBUG (\r
-        (EFI_D_BLKIO,\r
-        "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
-        StatusRegister)\r
-        );\r
-    }\r
+  if ((StatusRegister & ATA_STSREG_DWF) != 0) {\r
+    DEBUG (\r
+      (EFI_D_BLKIO,\r
+      "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
+      StatusRegister)\r
+      );\r
+  }\r
 \r
-    if ((StatusRegister & ATA_STSREG_CORR) != 0) {\r
-      DEBUG (\r
-        (EFI_D_BLKIO,\r
-        "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
-        StatusRegister)\r
-        );\r
-    }\r
+  if ((StatusRegister & ATA_STSREG_CORR) != 0) {\r
+    DEBUG (\r
+      (EFI_D_BLKIO,\r
+      "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
+      StatusRegister)\r
+      );\r
+   }\r
 \r
-    if ((StatusRegister & ATA_STSREG_ERR) != 0) {\r
-      ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+  if ((StatusRegister & ATA_STSREG_ERR) != 0) {\r
+    ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_BBK) != 0) {\r
+    if ((ErrorRegister & ATA_ERRREG_BBK) != 0) {\r
       DEBUG (\r
         (EFI_D_BLKIO,\r
         "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
@@ -712,25 +850,16 @@ CheckErrorStatus (
 }\r
 \r
 /**\r
-  This function is called by the AtaBlkIoReadBlocks() to perform\r
-  reading from media in block unit.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer\r
-  A pointer to the destination buffer for the data.\r
-\r
-  @param[in] Lba\r
-  The starting logical block address to read from\r
-  on the device media.\r
-\r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
-\r
-  @return return status is fully dependent on the return status\r
-  of AtaPioDataIn() function.\r
+  This function is called by the AtaBlkIoReadBlocks() to perform reading from \r
+  media in block unit.\r
+\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                        all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the destination buffer for the data.\r
+  @param Lba            The starting logical block address to read from on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
+  \r
+  @return status is fully dependent on the return status of AtaPioDataIn() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -830,25 +959,16 @@ AtaReadSectors (
 }\r
 \r
 /**\r
-  This function is called by the AtaBlkIoWriteBlocks() to perform\r
-  writing onto media in block unit.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure,used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *BufferData\r
-  A pointer to the source buffer for the data.\r
-\r
-  @param[in] Lba\r
-  The starting logical block address to write onto\r
-  the device media.\r
-\r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
-\r
-  @return return status is fully dependent on the return status\r
-  of AtaPioDataOut() function.\r
+  This function is called by the AtaBlkIoWriteBlocks() to perform writing onto \r
+  media in block unit.\r
+\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure,used to record\r
+                        all the information of the IDE device.\r
+  @param BufferData     A pointer to the source buffer for the data.\r
+  @param Lba            The starting logical block address to write onto the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
+  \r
+  @return status is fully dependent on the return status of AtaPioDataIn() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -933,12 +1053,10 @@ AtaWriteSectors (
 \r
   return Status;\r
 }\r
-\r
 /**\r
-  This function is used to implement the Soft Reset on the specified\r
-  device. But, the ATA Soft Reset mechanism is so strong a reset method\r
-  that it will force resetting on both devices connected to the\r
-  same cable.\r
+  This function is used to implement the Soft Reset on the specified device. But,\r
+  the ATA Soft Reset mechanism is so strong a reset method that it will force \r
+  resetting on both devices connected to the same cable.\r
 \r
   It is called by IdeBlkIoReset(), a interface function of Block\r
   I/O protocol.\r
@@ -946,17 +1064,13 @@ AtaWriteSectors (
   This function can also be used by the ATAPI device to perform reset when\r
   ATAPI Reset command is failed.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                 all the information of the IDE device.\r
   @retval EFI_SUCCESS       Soft reset completes successfully.\r
   @retval EFI_DEVICE_ERROR  Any step during the reset process is failed.\r
 \r
-  @note\r
-  The registers initial values after ATA soft reset are different\r
-  to the ATA device and ATAPI device.\r
-\r
+  @note  The registers initial values after ATA soft reset are different\r
+         to the ATA device and ATAPI device.\r
 **/\r
 EFI_STATUS\r
 AtaSoftReset (\r
@@ -1005,1015 +1119,1082 @@ AtaSoftReset (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
-  This function is the ATA implementation for ReadBlocks in the\r
-  Block I/O Protocol interface.\r
-\r
-  @param[in] *IdeBlkIoDevice\r
-  Indicates the calling context.\r
-\r
-  @param[in] MediaId\r
-  The media id that the read request is for.\r
+  This function is used to send out ATA commands conforms to the PIO Data In \r
+  Protocol, supporting ATA/ATAPI-6 standard\r
 \r
-  @param[in] LBA\r
-  The starting logical block address to read from\r
-  on the device.\r
-\r
-  @param[in] BufferSize\r
-  The size of the Buffer in bytes. This must be a\r
-  multiple of the intrinsic block size of the device.\r
-\r
-  @param[out] *Buffer\r
-  A pointer to the destination buffer for the data.\r
-  The caller is responsible for either having implicit\r
-  or explicit ownership of the memory that data is read into.\r
-\r
-  @retval EFI_SUCCESS       Read Blocks successfully.\r
-  @retval EFI_DEVICE_ERROR  Read Blocks failed.\r
-  @retval EFI_NO_MEDIA      There is no media in the device.\r
-  @retval EFI_MEDIA_CHANGE  The MediaId is not for the current media.\r
+  Comparing with ATA-3 data in protocol, we have two differents here:\r
+  1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+  wait will frequently fail... cause writing function return error)\r
 \r
-  @retval EFI_BAD_BUFFER_SIZE\r
-  The BufferSize parameter is not a multiple of the\r
-  intrinsic block size of the device.\r
+  2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+  slow down writing performance by 100 times!)\r
 \r
-  @retval EFI_INVALID_PARAMETER\r
-  The read request contains LBAs that are not valid,\r
-  or the data buffer is not valid.\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param Buffer       buffer contained data transferred from device to host.\r
+  @param ByteCount    data size in byte unit of the buffer.\r
+  @param AtaCommand   value of the Command Register\r
+  @param StartLba     the start LBA of this transaction\r
+  @param SectorCount  the count of sectors to be transfered\r
 \r
-  @note\r
-  If Read Block error because of device error, this function will call\r
-  AtaSoftReset() function to reset device.\r
+  @retval EFI_SUCCESS      send out the ATA command and device send required data successfully.\r
+  @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
 EFI_STATUS\r
-AtaBlkIoReadBlocks (\r
-  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
-  IN UINT32           MediaId,\r
-  IN EFI_LBA          LBA,\r
-  IN UINTN            BufferSize,\r
-  OUT VOID            *Buffer\r
+AtaPioDataInExt (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  OUT VOID        *Buffer,\r
+  IN  UINT32          ByteCount,\r
+  IN  UINT8           AtaCommand,\r
+  IN  EFI_LBA         StartLba,\r
+  IN  UINT16          SectorCount\r
   )\r
 {\r
-  EFI_BLOCK_IO_MEDIA  *Media;\r
-  UINTN               BlockSize;\r
-  UINTN               NumberOfBlocks;\r
-  EFI_STATUS          Status;\r
+  UINT8       DevSel;\r
+  UINT8       SectorCount8;\r
+  UINT8       LbaLow;\r
+  UINT8       LbaMid;\r
+  UINT8       LbaHigh;\r
+  UINTN       WordCount;\r
+  UINTN       Increment;\r
+  UINT16      *Buffer16;\r
+  EFI_STATUS  Status;\r
 \r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
+  //\r
+  // Select device, set bit6 as 1 to indicate LBA mode is used\r
+  //\r
+  DevSel = (UINT8) (IdeDev->Device << 4);\r
+  DevSel |= 0x40;\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    DevSel\r
+    );\r
+\r
+  //\r
+  // Wait for DRDY singnal asserting. ATAPI device needn't wait\r
+  //\r
+  if ( (IdeDev->Type == IdeHardDisk)  ||\r
+        (IdeDev->Type == Ide48bitAddressingHardDisk)) {\r
+\r
+    Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
+  //\r
+  // Fill feature register if needed\r
+  //\r
+  if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
+  }\r
 \r
   //\r
-  //  Get the intrinsic block size\r
+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
   //\r
-  Media           = IdeBlkIoDevice->BlkIo.Media;\r
-  BlockSize       = Media->BlockSize;\r
+  SectorCount8 = (UINT8) (SectorCount >> 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
 \r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  SectorCount8 = (UINT8) SectorCount;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
 \r
-  if (MediaId != Media->MediaId) {\r
-    return EFI_MEDIA_CHANGED;\r
-  }\r
+  //\r
+  // Fill the start LBA registers, which are also two-byte FIFO\r
+  //\r
+  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);\r
+  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);\r
+  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
-  if (BufferSize % BlockSize != 0) {\r
-    return EFI_BAD_BUFFER_SIZE;\r
-  }\r
+  LbaLow  = (UINT8) StartLba;\r
+  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);\r
+  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
-  if (!(Media->MediaPresent)) {\r
-    return EFI_NO_MEDIA;\r
-  }\r
+  //\r
+  // Send command via Command Register, invoking the processing of this command\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
 \r
-  if (LBA > Media->LastBlock) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  Buffer16 = (UINT16 *) Buffer;\r
 \r
-  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  //\r
+  // According to PIO data in protocol, host can perform a series of reads to\r
+  // the data register after each time device set DRQ ready;\r
+  //\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  //\r
+  // 256 words\r
+  //\r
+  Increment = 256;\r
 \r
-  Status = EFI_SUCCESS;\r
-  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+  //\r
+  // used to record bytes of currently transfered data\r
+  //\r
+  WordCount = 0;\r
+\r
+  while (WordCount < ByteCount / 2) {\r
     //\r
-    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism\r
+    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
     //\r
-    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
-      Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    } else {\r
-      Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+    Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
     }\r
-  } else {\r
+\r
+    Status = CheckErrorStatus (IdeDev);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
     //\r
-    // For ATA-3 compatible device, use ATA-3 read block mechanism\r
+    // Get the byte count for one series of read\r
     //\r
-    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
-      Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    } else {\r
-      Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+    if ((WordCount + Increment) > ByteCount / 2) {\r
+      Increment = ByteCount / 2 - WordCount;\r
     }\r
-  }\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    AtaSoftReset (IdeBlkIoDevice);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+    IDEReadPortWMultiple (\r
+      IdeDev->PciIo,\r
+      IdeDev->IoPort->Data,\r
+      Increment,\r
+      Buffer16\r
+      );\r
 \r
-  return EFI_SUCCESS;\r
+    WordCount += Increment;\r
+    Buffer16 += Increment;\r
 \r
-}\r
+  }\r
 \r
+  return CheckErrorStatus (IdeDev);\r
+}\r
 /**\r
-  This function is the ATA implementation for WriteBlocks in the\r
-  Block I/O Protocol interface.\r
-\r
-  @param[in] *IdeBlkIoDevice\r
-  Indicates the calling context.\r
-\r
-  @param[in] MediaId\r
-  The media id that the write request is for.\r
-\r
-  @param[in] LBA\r
-  The starting logical block address to write onto\r
-  the device.\r
-\r
-  @param[in] BufferSize\r
-  The size of the Buffer in bytes. This must be a\r
-  multiple of the intrinsic block size of the device.\r
-\r
-  @param[out] *Buffer\r
-  A pointer to the source buffer for the data.\r
-  The caller is responsible for either having implicit\r
-  or explicit ownership of the memory that data is\r
-  written from.\r
-\r
-  @retval EFI_SUCCESS       Write Blocks successfully.\r
-  @retval EFI_DEVICE_ERROR  Write Blocks failed.\r
-  @retval EFI_NO_MEDIA      There is no media in the device.\r
-  @retval EFI_MEDIA_CHANGE  The MediaId is not for the current media.\r
-\r
-  @retval EFI_BAD_BUFFER_SIZE\r
-  The BufferSize parameter is not a multiple of the\r
-  intrinsic block size of the device.\r
+  Send ATA Ext command into device with NON_DATA protocol\r
 \r
-  @retval EFI_INVALID_PARAMETER\r
-  The write request contains LBAs that are not valid,\r
-  or the data buffer is not valid.\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaAddress The LBA address in 48-bit mode\r
 \r
-  @note\r
-  If Write Block error because of device error, this function will call\r
-  AtaSoftReset() function to reset device.\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_DEVICE_ERROR Error executing commands on this device.\r
 \r
 **/\r
 EFI_STATUS\r
-AtaBlkIoWriteBlocks (\r
-  IN  IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
-  IN  UINT32           MediaId,\r
-  IN  EFI_LBA          LBA,\r
-  IN  UINTN            BufferSize,\r
-  OUT VOID             *Buffer\r
+AtaCommandIssueExt (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  UINT8           AtaCommand,\r
+  IN  UINT8           Device,\r
+  IN  UINT16          Feature,\r
+  IN  UINT16          SectorCount,\r
+  IN  EFI_LBA         LbaAddress\r
   )\r
 {\r
+  EFI_STATUS  Status;\r
+  UINT8       SectorCount8;\r
+  UINT8       Feature8;\r
+  UINT8       LbaLow;\r
+  UINT8       LbaMid;\r
+  UINT8       LbaHigh;\r
 \r
-  EFI_BLOCK_IO_MEDIA  *Media;\r
-  UINTN               BlockSize;\r
-  UINTN               NumberOfBlocks;\r
-  EFI_STATUS          Status;\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
+  //\r
+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+  //\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+    );\r
+\r
+  //\r
+  // ATA commands for ATA device must be issued when DRDY is set\r
+  //\r
+  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
+  //\r
+  // Pass parameter into device register block\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
 \r
   //\r
-  // Get the intrinsic block size\r
+  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
   //\r
-  Media           = IdeBlkIoDevice->BlkIo.Media;\r
-  BlockSize       = Media->BlockSize;\r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  Feature8 = (UINT8) (Feature >> 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
 \r
-  if (MediaId != Media->MediaId) {\r
-    return EFI_MEDIA_CHANGED;\r
-  }\r
+  Feature8 = (UINT8) Feature;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
 \r
-  if (BufferSize % BlockSize != 0) {\r
-    return EFI_BAD_BUFFER_SIZE;\r
-  }\r
+  //\r
+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+  //\r
+  SectorCount8 = (UINT8) (SectorCount >> 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
 \r
-  if (LBA > Media->LastBlock) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  SectorCount8 = (UINT8) SectorCount;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
 \r
-  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  //\r
+  // Fill the start LBA registers, which are also two-byte FIFO\r
+  //\r
+  LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  LbaLow = (UINT8) LbaAddress;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
 \r
-  Status = EFI_SUCCESS;\r
-  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
-    //\r
-    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism\r
-    //\r
-    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
-      Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    } else {\r
-      Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    }\r
-  } else {\r
-    //\r
-    // For ATA-3 compatible device, use ATA-3 write block mechanism\r
-    //\r
-    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
-      Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    } else {\r
-      Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
-    }\r
-  }\r
+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    AtaSoftReset (IdeBlkIoDevice);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+  //\r
+  // Work around for Segate 160G disk writing\r
+  //\r
+  gBS->Stall (1800);\r
+\r
+  //\r
+  // Send command via Command Register\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+  //\r
+  // Stall at least 400ns\r
+  //\r
+  gBS->Stall (100);\r
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
-  This function is called by the AtaBlkIoReadBlocks() to perform\r
-  reading from media in block unit. The function has been enhanced to\r
-  support >120GB access and transfer at most 65536 blocks per command\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  Send ATA Ext command into device with NON_DATA protocol\r
 \r
-  @param[in] *DataBuffer    A pointer to the destination buffer for the data.\r
-  @param[in] StartLba       The starting logical block address to read from\r
-  on the device media.\r
-  @param[in] NumberOfBlocks The number of transfer data blocks.\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaAddress The LBA address in 48-bit mode\r
 \r
-  @return return status is fully dependent on the return status\r
-  of AtaPioDataInExt() function.\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_DEVICE_ERROR Error executing commands on this device.\r
 \r
 **/\r
 EFI_STATUS\r
-AtaReadSectorsExt (\r
+AtaCommandIssue (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
+  IN  UINT8           AtaCommand,\r
+  IN  UINT8           Device,\r
+  IN  UINT16          Feature,\r
+  IN  UINT16          SectorCount,\r
+  IN  EFI_LBA         LbaAddress\r
   )\r
 {\r
   EFI_STATUS  Status;\r
-  UINTN       BlocksRemaining;\r
-  EFI_LBA     Lba64;\r
-  UINT8       AtaCommand;\r
-  UINT16      SectorCount;\r
-  UINT32      ByteCount;\r
-  VOID        *Buffer;\r
+  UINT8       SectorCount8;\r
+  UINT8       Feature8;\r
+  UINT8       Lba0;\r
+  UINT8       Lba1;\r
+  UINT8       Lba2;\r
+  UINT8       Lba3;\r
+\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   //\r
-  // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol\r
+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
   //\r
-  AtaCommand      = ATA_CMD_READ_SECTORS_EXT;\r
-  Buffer          = DataBuffer;\r
-  BlocksRemaining = NumberOfBlocks;\r
-  Lba64           = StartLba;\r
-  Status          = EFI_SUCCESS;\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+    );\r
 \r
-  while (BlocksRemaining > 0) {\r
+  //\r
+  // ATA commands for ATA device must be issued when DRDY is set\r
+  //\r
+  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-    if (BlocksRemaining >= 0x10000) {\r
-      //\r
-      //  SectorCount is used to record the number of sectors to be read\r
-      //  Max 65536 sectors can be transfered at a time.\r
-      //\r
-      SectorCount = 0xffff;\r
-    } else {\r
-      SectorCount = (UINT16) BlocksRemaining;\r
-    }\r
+  Lba0  = (UINT8) LbaAddress;\r
+  Lba1  = (UINT8) RShiftU64 (LbaAddress, 8);\r
+  Lba2  = (UINT8) RShiftU64 (LbaAddress, 16);\r
+  Lba3  = (UINT8) RShiftU64 (LbaAddress, 24);\r
+  Device = (UINT8) (Device | Lba3);\r
 \r
-    //\r
-    // ByteCount is the number of bytes that will be read\r
-    //\r
-    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+  //\r
+  // Pass parameter into device register block\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
 \r
-    //\r
-    // call AtaPioDataInExt() to send Read Sector Command and receive data read\r
-    //\r
-    Status = AtaPioDataInExt (\r
-              IdeDev,\r
-              Buffer,\r
-              ByteCount,\r
-              AtaCommand,\r
-              Lba64,\r
-              SectorCount\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  //\r
+  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+  //\r
+  Feature8 = (UINT8) Feature;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
 \r
-    Lba64 += SectorCount;\r
-    Buffer = ((UINT8 *) Buffer + ByteCount);\r
-    BlocksRemaining -= SectorCount;\r
-  }\r
+  //\r
+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+  //\r
+  SectorCount8 = (UINT8) SectorCount;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
 \r
-  return Status;\r
-}\r
+  //\r
+  // Fill the start LBA registers, which are also two-byte FIFO\r
+  //\r
 \r
-/**\r
-  This function is called by the AtaBlkIoWriteBlocks() to perform\r
-  writing onto media in block unit. The function has been enhanced to\r
-  support >120GB access and transfer at most 65536 blocks per command\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure,used\r
-  to record all the information of the IDE device.\r
+  //\r
+  // Send command via Command Register\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
 \r
-  @param[in] *DataBuffer\r
-  A pointer to the source buffer for the data.\r
+  //\r
+  // Stall at least 400ns\r
+  //\r
+  gBS->Stall (100);\r
 \r
-  @param[in] StartLba\r
-  The starting logical block address to write onto\r
-  the device media.\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
 \r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                        to record all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the source buffer for the data.\r
+  @param StartLba       The starting logical block address to write to\r
+                        on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
+  @param UdmaOp         The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
+                        AtaUdmaWriteOp, AtaUdmaWriteExOp\r
 \r
-  @return status is fully dependent on the return status\r
-  of AtaPioDataOutExt() function.\r
+  @retval EFI_SUCCESS          the operation is successful.\r
+  @retval EFI_OUT_OF_RESOURCES Build PRD table failed\r
+  @retval EFI_UNSUPPORTED      Unknown channel or operations command\r
+  @retval EFI_DEVICE_ERROR     Ata command execute failed\r
 \r
 **/\r
 EFI_STATUS\r
-AtaWriteSectorsExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
+DoAtaUdma (\r
+  IN  IDE_BLK_IO_DEV      *IdeDev,\r
+  IN  VOID                *DataBuffer,\r
+  IN  EFI_LBA             StartLba,\r
+  IN  UINTN               NumberOfBlocks,\r
+  IN  ATA_UDMA_OPERATION  UdmaOp\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  EFI_LBA     Lba64;\r
-  UINTN       BlocksRemaining;\r
-  UINT8       AtaCommand;\r
-  UINT16      SectorCount;\r
-  UINT32      ByteCount;\r
-  VOID        *Buffer;\r
+  IDE_DMA_PRD                   *PrdAddr;\r
+  IDE_DMA_PRD                   *UsedPrdAddr;\r
+  IDE_DMA_PRD                   *TempPrdAddr;\r
+  UINT8                         RegisterValue;\r
+  UINT8                         Device;\r
+  UINT64                        IoPortForBmic;\r
+  UINT64                        IoPortForBmis;\r
+  UINT64                        IoPortForBmid;\r
+  EFI_STATUS                    Status;\r
+  UINTN                         PrdTableNum;\r
+  UINTN                         ByteCount;\r
+  UINTN                         ByteAvailable;\r
+  UINT8                         *PrdBuffer;\r
+  UINTN                         RemainBlockNum;\r
+  UINT8                         DeviceControl;\r
+  UINT32                        Count;\r
+  UINTN                         PageCount;\r
+  VOID                          *Map;\r
+  VOID                          *MemPage;\r
+  EFI_PHYSICAL_ADDRESS          DeviceAddress;\r
+  UINTN                         MaxDmaCommandSectors;\r
+  EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;\r
+  UINT8                         AtaCommand;\r
+\r
+  switch (UdmaOp) {\r
+  case AtaUdmaReadOp:\r
+    MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
+    PciIoProtocolOp      = EfiPciIoOperationBusMasterWrite;\r
+    AtaCommand           = ATA_CMD_READ_DMA;\r
+    break;\r
+  case AtaUdmaReadExtOp:\r
+    MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
+    PciIoProtocolOp      = EfiPciIoOperationBusMasterWrite;\r
+    AtaCommand           = ATA_CMD_READ_DMA_EXT;\r
+    break;\r
+  case AtaUdmaWriteOp:\r
+    MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
+    PciIoProtocolOp      = EfiPciIoOperationBusMasterRead;\r
+    AtaCommand           = ATA_CMD_WRITE_DMA;\r
+    break;\r
+  case AtaUdmaWriteExtOp:\r
+    MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
+    PciIoProtocolOp      = EfiPciIoOperationBusMasterRead;\r
+    AtaCommand           = ATA_CMD_WRITE_DMA_EXT;\r
+    break;\r
+  default:\r
+    return EFI_UNSUPPORTED;\r
+    break;\r
+  }\r
 \r
   //\r
-  // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol\r
+  // Select device\r
   //\r
-  AtaCommand      = ATA_CMD_WRITE_SECTORS_EXT;\r
-  Lba64           = StartLba;\r
-  Buffer          = DataBuffer;\r
-  BlocksRemaining = NumberOfBlocks;\r
+  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
 \r
-  Status          = EFI_SUCCESS;\r
+  //\r
+  // Enable interrupt to support UDMA\r
+  //\r
+  DeviceControl = 0;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
 \r
-  while (BlocksRemaining > 0) {\r
+  if (IdePrimary == IdeDev->Channel) {\r
+    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;\r
+    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
+    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;\r
+  } else {\r
+    if (IdeSecondary == IdeDev->Channel) {\r
+      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;\r
+      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
+      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;\r
+    } else {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
 \r
-    if (BlocksRemaining >= 0x10000) {\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
+  Status = EFI_SUCCESS;\r
+  \r
+  RemainBlockNum = NumberOfBlocks;\r
+  while (RemainBlockNum > 0) {\r
+\r
+    if (RemainBlockNum >= MaxDmaCommandSectors) {\r
       //\r
-      //  SectorCount is used to record the number of sectors to be written.\r
+      //  SectorCount is used to record the number of sectors to be read\r
       //  Max 65536 sectors can be transfered at a time.\r
       //\r
-      SectorCount = 0xffff;\r
+      NumberOfBlocks = MaxDmaCommandSectors;\r
+      RemainBlockNum -= MaxDmaCommandSectors;\r
     } else {\r
-      SectorCount = (UINT16) BlocksRemaining;\r
+      NumberOfBlocks  = (UINT16) RemainBlockNum;\r
+      RemainBlockNum  = 0;\r
     }\r
 \r
     //\r
-    // ByteCount is the number of bytes that will be written\r
+    // Calculate the number of PRD table to make sure the memory region\r
+    // not cross 64K boundary\r
     //\r
-    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
+    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
+    PrdTableNum = ((ByteCount >> 16) + 1) + 1;\r
 \r
     //\r
-    // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command\r
+    // Build PRD table\r
     //\r
-    Status = AtaPioDataOutExt (\r
-              IdeDev,\r
-              Buffer,\r
-              ByteCount,\r
-              AtaCommand,\r
-              Lba64,\r
-              SectorCount\r
-              );\r
+    PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+    Status = IdeDev->PciIo->AllocateBuffer (\r
+                    IdeDev->PciIo,\r
+                    AllocateAnyPages,\r
+                    EfiBootServicesData,\r
+                    PageCount,\r
+                    &MemPage,\r
+                    0\r
+                    );\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      return EFI_OUT_OF_RESOURCES;\r
     }\r
+    ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
 \r
-    Lba64 += SectorCount;\r
-    Buffer = ((UINT8 *) Buffer + ByteCount);\r
-    BlocksRemaining -= SectorCount;\r
-  }\r
-\r
-  return Status;\r
-}\r
+    PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
+    //\r
+    // To make sure PRD is allocated in one 64K page\r
+    //\r
+    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {\r
+      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);\r
+    } else {\r
+      if ((UINTN) PrdAddr & 0x03) {\r
+        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);\r
+      } else {\r
+        UsedPrdAddr = PrdAddr;\r
+      }\r
+    }\r
 \r
-/**\r
-  This function is used to send out ATA commands conforms to the\r
-  PIO Data In Protocol, supporting ATA/ATAPI-6 standard\r
-\r
-  Comparing with ATA-3 data in protocol, we have two differents here:<BR>\r
-  1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
-  wait will frequently fail... cause writing function return error)\r
+    //\r
+    // Build the PRD table\r
+    //\r
+    Status = IdeDev->PciIo->Map (\r
+                       IdeDev->PciIo,\r
+                       PciIoProtocolOp,\r
+                       DataBuffer,\r
+                       &ByteCount,\r
+                       &DeviceAddress,\r
+                       &Map\r
+                       );\r
+    if (EFI_ERROR (Status)) {\r
+      IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    PrdBuffer   = (VOID *) ((UINTN) DeviceAddress);\r
+    TempPrdAddr = UsedPrdAddr;\r
+    while (TRUE) {\r
 \r
-  2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
-  slow down writing performance by 100 times!)\r
+      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);\r
 \r
-  @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+      if (ByteCount <= ByteAvailable) {\r
+        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
+        TempPrdAddr->ByteCount      = (UINT16) ByteCount;\r
+        TempPrdAddr->EndOfTable     = 0x8000;\r
+        break;\r
+      }\r
 \r
-  @param[in, out] *Buffer  buffer contained data transferred from device to host.\r
-  @param[in] ByteCount    data size in byte unit of the buffer.\r
-  @param[in] AtaCommand   value of the Command Register\r
-  @param[in] StartLba     the start LBA of this transaction\r
-  @param[in] SectorCount  the count of sectors to be transfered\r
+      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
+      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;\r
 \r
-  @retval EFI_SUCCESS send out the ATA command and device send required\r
-  data successfully.\r
+      ByteCount -= ByteAvailable;\r
+      PrdBuffer += ByteAvailable;\r
+      TempPrdAddr++;\r
+    }\r
 \r
-  @retval EFI_DEVICE_ERROR command sent failed.\r
+    //\r
+    // Set the base address to BMID register\r
+    //\r
+    IdeDev->PciIo->Io.Write (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint32,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmid,\r
+                        1,\r
+                        &UsedPrdAddr\r
+                        );\r
 \r
-**/\r
-EFI_STATUS\r
-AtaPioDataInExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  OUT VOID        *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  UINT8           AtaCommand,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINT16          SectorCount\r
-  )\r
-{\r
-  UINT8       DevSel;\r
-  UINT8       SectorCount8;\r
-  UINT8       LbaLow;\r
-  UINT8       LbaMid;\r
-  UINT8       LbaHigh;\r
-  UINTN       WordCount;\r
-  UINTN       Increment;\r
-  UINT16      *Buffer16;\r
-  EFI_STATUS  Status;\r
+    //\r
+    // Set BMIC register to identify the operation direction\r
+    //\r
+    IdeDev->PciIo->Io.Read (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+    if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {\r
+      RegisterValue |= BMIC_NREAD;\r
+    } else {\r
+      RegisterValue &= ~((UINT8) BMIC_NREAD);\r
+    }\r
 \r
-  //\r
-  // Select device, set bit6 as 1 to indicate LBA mode is used\r
-  //\r
-  DevSel = (UINT8) (IdeDev->Device << 4);\r
-  DevSel |= 0x40;\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    DevSel\r
-    );\r
+    IdeDev->PciIo->Io.Write (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-  //\r
-  // Wait for DRDY singnal asserting. ATAPI device needn't wait\r
-  //\r
-  if ( (IdeDev->Type == IdeHardDisk)  ||\r
-        (IdeDev->Type == Ide48bitAddressingHardDisk)) {\r
+    if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {\r
+      Status = AtaCommandIssueExt (\r
+                 IdeDev,\r
+                 AtaCommand,\r
+                 Device,\r
+                 0,\r
+                 (UINT16) NumberOfBlocks,\r
+                 StartLba\r
+                 );\r
+    } else {\r
+      Status = AtaCommandIssue (\r
+                 IdeDev,\r
+                 AtaCommand,\r
+                 Device,\r
+                 0,\r
+                 (UINT16) NumberOfBlocks,\r
+                 StartLba\r
+                 );\r
+    }\r
 \r
-    Status = DRDYReady (IdeDev, ATATIMEOUT);\r
     if (EFI_ERROR (Status)) {\r
+      IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+      IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
       return EFI_DEVICE_ERROR;\r
     }\r
-  }\r
-\r
-  //\r
-  // Fill feature register if needed\r
-  //\r
-  if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
-    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
-  }\r
-\r
-  //\r
-  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
-  //\r
-  SectorCount8 = (UINT8) (SectorCount >> 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
-  SectorCount8 = (UINT8) SectorCount;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
-  //\r
-  // Fill the start LBA registers, which are also two-byte FIFO\r
-  //\r
-  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);\r
-  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);\r
-  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
-  LbaLow  = (UINT8) StartLba;\r
-  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);\r
-  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
-  //\r
-  // Send command via Command Register, invoking the processing of this command\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
-  Buffer16 = (UINT16 *) Buffer;\r
-\r
-  //\r
-  // According to PIO data in protocol, host can perform a series of reads to\r
-  // the data register after each time device set DRQ ready;\r
-  //\r
+    //\r
+    // Set START bit of BMIC register\r
+    //\r
+    IdeDev->PciIo->Io.Read (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-  //\r
-  // 256 words\r
-  //\r
-  Increment = 256;\r
+    RegisterValue |= BMIC_START;\r
 \r
-  //\r
-  // used to record bytes of currently transfered data\r
-  //\r
-  WordCount = 0;\r
+    IdeDev->PciIo->Io.Write (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-  while (WordCount < ByteCount / 2) {\r
     //\r
-    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+    // Check the INTERRUPT and ERROR bit of BMIS\r
+    // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+    // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+    // So set the variable Count to 2000, for about 2 second timeout time.\r
     //\r
-    Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
+    Status = EFI_SUCCESS;\r
+    Count = 2000;\r
+    while (TRUE) {\r
 \r
-    Status = CheckErrorStatus (IdeDev);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\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
+      if (((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) != 0) || (Count == 0)) {\r
+        if (((RegisterValue & BMIS_ERROR) != 0) || (Count == 0)) {\r
+                 Status = EFI_DEVICE_ERROR;\r
+                 break;\r
+        }\r
+        break;\r
+      }\r
+\r
+      gBS->Stall (1000);\r
+      Count --;\r
     }\r
 \r
+    IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+    IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
     //\r
-    // Get the byte count for one series of read\r
+    // Read BMIS register and clear ERROR and INTR bit\r
     //\r
-    if ((WordCount + Increment) > ByteCount / 2) {\r
-      Increment = ByteCount / 2 - WordCount;\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
-    IDEReadPortWMultiple (\r
-      IdeDev->PciIo,\r
-      IdeDev->IoPort->Data,\r
-      Increment,\r
-      Buffer16\r
-      );\r
+    RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
 \r
-    WordCount += Increment;\r
-    Buffer16 += Increment;\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
+    // Read Status Register of IDE device to clear interrupt\r
+    //\r
+    RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+    //\r
+    // Clear START bit of BMIC register\r
+    //\r
+    IdeDev->PciIo->Io.Read (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-  }\r
+    RegisterValue &= ~((UINT8) BMIC_START);\r
 \r
-  return CheckErrorStatus (IdeDev);\r
-}\r
+    IdeDev->PciIo->Io.Write (\r
+                        IdeDev->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                        IoPortForBmic,\r
+                        1,\r
+                        &RegisterValue\r
+                        );\r
 \r
-/**\r
-  This function is used to send out ATA commands conforms to the\r
-  PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
+    if ((RegisterValue & BMIS_ERROR) != 0) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
 \r
-  Comparing with ATA-3 data out protocol, we have two differents here:<BR>\r
-  1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
-  wait will frequently fail... cause writing function return error)\r
+       if (EFI_ERROR (Status)) {\r
+         break;\r
+       }\r
+    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
+    StartLba += NumberOfBlocks;\r
+  }\r
 \r
-  2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
-  slow down writing performance by 100 times!)\r
+  //\r
+  // Disable interrupt of Select device\r
+  //\r
+  IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+  DeviceControl |= ATA_CTLREG_IEN_L;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  return Status;\r
+}\r
 \r
-  @param[in] *Buffer      buffer contained data transferred from host to device.\r
-  @param[in] ByteCount    data size in byte unit of the buffer.\r
-  @param[in] AtaCommand   value of the Command Register\r
-  @param[in] StartLba     the start LBA of this transaction\r
-  @param[in] SectorCount  the count of sectors to be transfered\r
 \r
-  @retval EFI_SUCCESS send out the ATA command and device receive required\r
-  data successfully.\r
+/**\r
+  This function is called by the AtaBlkIoReadBlocks() to perform reading from\r
+  media in block unit. The function has been enhanced to support >120GB access \r
+  and transfer at most 65536 blocks per command\r
 \r
-  @retval EFI_DEVICE_ERROR command sent failed.\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                        all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the destination buffer for the data.\r
+  @param StartLba       The starting logical block address to read from on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
 \r
+  @return status depends on the function DoAtaUdma() returns.\r
 **/\r
 EFI_STATUS\r
-AtaPioDataOutExt (\r
+AtaUdmaReadExt (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  UINT8           AtaCommand,\r
+  IN  VOID            *DataBuffer,\r
   IN  EFI_LBA         StartLba,\r
-  IN  UINT16          SectorCount\r
+  IN  UINTN           NumberOfBlocks\r
   )\r
 {\r
-  UINT8       DevSel;\r
-  UINT8       SectorCount8;\r
-  UINT8       LbaLow;\r
-  UINT8       LbaMid;\r
-  UINT8       LbaHigh;\r
-  UINTN       WordCount;\r
-  UINTN       Increment;\r
-  UINT16      *Buffer16;\r
-  EFI_STATUS  Status;\r
-\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Select device. Set bit6 as 1 to indicate LBA mode is used\r
-  //\r
-  DevSel = (UINT8) (IdeDev->Device << 4);\r
-  DevSel |= 0x40;\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    DevSel\r
-    );\r
-\r
-  //\r
-  // Wait for DRDY singnal asserting.\r
-  //\r
-  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Fill feature register if needed\r
-  //\r
-  if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
-    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
-  }\r
+  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);\r
+}\r
+/**\r
+  This function is called by the AtaBlkIoReadBlocks() to perform\r
+  reading from media in block unit. The function has been enhanced to\r
+  support >120GB access and transfer at most 65536 blocks per command\r
 \r
-  //\r
-  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
-  //\r
-  SectorCount8 = (UINT8) (SectorCount >> 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                        all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the destination buffer for the data.\r
+  @param StartLba       The starting logical block address to read from\r
+                        on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
+  \r
+  @return status depends on the function DoAtaUdma() returns.\r
+**/\r
+EFI_STATUS\r
+AtaUdmaRead (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  VOID            *DataBuffer,\r
+  IN  EFI_LBA         StartLba,\r
+  IN  UINTN           NumberOfBlocks\r
+  )\r
+{\r
+  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);\r
+}\r
 \r
-  SectorCount8 = (UINT8) SectorCount;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+/**\r
+  This function is called by the AtaBlkIoReadBlocks() to perform\r
+  reading from media in block unit. The function has been enhanced to\r
+  support >120GB access and transfer at most 65536 blocks per command\r
 \r
-  //\r
-  // Fill the start LBA registers, which are also two-byte FIFO\r
-  //\r
-  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);\r
-  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);\r
-  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                        all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the destination buffer for the data.\r
+  @param StartLba       The starting logical block address to read from on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
 \r
-  LbaLow  = (UINT8) StartLba;\r
-  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);\r
-  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+  @return status is fully dependent on the return status of AtaPioDataInExt() function.\r
+**/\r
+EFI_STATUS\r
+AtaReadSectorsExt (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  VOID            *DataBuffer,\r
+  IN  EFI_LBA         StartLba,\r
+  IN  UINTN           NumberOfBlocks\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       BlocksRemaining;\r
+  EFI_LBA     Lba64;\r
+  UINT8       AtaCommand;\r
+  UINT16      SectorCount;\r
+  UINT32      ByteCount;\r
+  VOID        *Buffer;\r
 \r
   //\r
-  // Send command via Command Register, invoking the processing of this command\r
+  // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol\r
   //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
-  Buffer16 = (UINT16 *) Buffer;\r
+  AtaCommand      = ATA_CMD_READ_SECTORS_EXT;\r
+  Buffer          = DataBuffer;\r
+  BlocksRemaining = NumberOfBlocks;\r
+  Lba64           = StartLba;\r
+  Status          = EFI_SUCCESS;\r
 \r
-  //\r
-  // According to PIO Data Out protocol, host can perform a series of writes to\r
-  // the data register after each time device set DRQ ready;\r
-  //\r
-  Increment = 256;\r
+  while (BlocksRemaining > 0) {\r
 \r
-  //\r
-  // used to record bytes of currently transfered data\r
-  //\r
-  WordCount = 0;\r
+    if (BlocksRemaining >= 0x10000) {\r
+      //\r
+      //  SectorCount is used to record the number of sectors to be read\r
+      //  Max 65536 sectors can be transfered at a time.\r
+      //\r
+      SectorCount = 0xffff;\r
+    } else {\r
+      SectorCount = (UINT16) BlocksRemaining;\r
+    }\r
 \r
-  while (WordCount < ByteCount / 2) {\r
     //\r
-    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+    // ByteCount is the number of bytes that will be read\r
     //\r
-    Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-\r
-    Status = CheckErrorStatus (IdeDev);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
 \r
     //\r
-    // Write data into device by one series of writing to data register\r
+    // call AtaPioDataInExt() to send Read Sector Command and receive data read\r
     //\r
-    if ((WordCount + Increment) > ByteCount / 2) {\r
-      Increment = ByteCount / 2 - WordCount;\r
+    Status = AtaPioDataInExt (\r
+              IdeDev,\r
+              Buffer,\r
+              ByteCount,\r
+              AtaCommand,\r
+              Lba64,\r
+              SectorCount\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
 \r
-    IDEWritePortWMultiple (\r
-      IdeDev->PciIo,\r
-      IdeDev->IoPort->Data,\r
-      Increment,\r
-      Buffer16\r
-      );\r
-\r
-    WordCount += Increment;\r
-    Buffer16 += Increment;\r
-\r
+    Lba64 += SectorCount;\r
+    Buffer = ((UINT8 *) Buffer + ByteCount);\r
+    BlocksRemaining -= SectorCount;\r
   }\r
-  //\r
-  // while\r
-  //\r
 \r
-  return CheckErrorStatus (IdeDev);\r
+  return Status;\r
 }\r
+/**\r
+  This function is the ATA implementation for ReadBlocks in the\r
+  Block I/O Protocol interface.\r
 \r
+  @param IdeBlkIoDevice Indicates the calling context.\r
+  @param MediaId        The media id that the read request is for.\r
+  @param LBA            The starting logical block address to read from on the device.\r
+  @param BufferSize     The size of the Buffer in bytes. This must be a  multiple\r
+                        of the intrinsic block size of the device.\r
 \r
-/**\r
-  Enable SMART of the disk if supported\r
+  @param Buffer         A pointer to the destination buffer for the data. The caller\r
+                        is responsible for either having implicit or explicit ownership\r
+                        of the memory that data is read into.\r
+\r
+  @retval EFI_SUCCESS          Read Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR     Read Blocks failed.\r
+  @retval EFI_NO_MEDIA         There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE  The BufferSize parameter is not a multiple of the\r
+                               intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER  The read request contains LBAs that are not valid,\r
+                                 or the data buffer is not valid.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure,used\r
-  to record all the information of the IDE device.\r
+  @note If Read Block error because of device error, this function will call\r
+        AtaSoftReset() function to reset device.\r
 \r
 **/\r
-VOID\r
-AtaSMARTSupport (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
+EFI_STATUS\r
+AtaBlkIoReadBlocks (\r
+  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
+  IN UINT32           MediaId,\r
+  IN EFI_LBA          LBA,\r
+  IN UINTN            BufferSize,\r
+  OUT VOID            *Buffer\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  BOOLEAN           SMARTSupported;\r
-  UINT8             Device;\r
-  EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;\r
-  UINT8             DeviceSelect;\r
-  UINT8             LBAMid;\r
-  UINT8             LBAHigh;\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  UINTN               BlockSize;\r
+  UINTN               NumberOfBlocks;\r
+  EFI_STATUS          Status;\r
+\r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BufferSize == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   //\r
-  // Detect if the device supports S.M.A.R.T.\r
+  //  Get the intrinsic block size\r
   //\r
-  if ((IdeDev->IdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {\r
-    //\r
-    // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)\r
-    //\r
-    return ;\r
-  } else {\r
-    if ((IdeDev->IdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {\r
-      //\r
-      // S.M.A.R.T is not supported by the device\r
-      //\r
-      SMARTSupported = FALSE;\r
-    } else {\r
-      SMARTSupported = TRUE;\r
-    }\r
+  Media           = IdeBlkIoDevice->BlkIo.Media;\r
+  BlockSize       = Media->BlockSize;\r
+\r
+  NumberOfBlocks  = BufferSize / BlockSize;\r
+\r
+  if (MediaId != Media->MediaId) {\r
+    return EFI_MEDIA_CHANGED;\r
   }\r
 \r
-  if (!SMARTSupported) {\r
-    //\r
-    // Report nonsupport status code\r
-    //\r
-    REPORT_STATUS_CODE (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)\r
-      );\r
-  } else {\r
-    //\r
-    // Enable this feature\r
-    //\r
-    REPORT_STATUS_CODE (\r
-      EFI_PROGRESS_CODE,\r
-      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)\r
-      );\r
+  if (BufferSize % BlockSize != 0) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
 \r
-    Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
-    Status = AtaNonDataCommandIn (\r
-              IdeDev,\r
-              ATA_CMD_SMART,\r
-              Device,\r
-              ATA_SMART_ENABLE_OPERATION,\r
-              0,\r
-              0,\r
-              ATA_CONSTANT_4F,\r
-              ATA_CONSTANT_C2\r
-              );\r
+  if (!(Media->MediaPresent)) {\r
+    return EFI_NO_MEDIA;\r
+  }\r
+\r
+  if (LBA > Media->LastBlock) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
     //\r
-    // Detect if this feature is enabled\r
+    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism\r
     //\r
-    TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));\r
-    if (TmpAtaIdentifyPointer == NULL) {\r
-      return;\r
-    }\r
-\r
-    DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);\r
-    Status = AtaPioDataIn (\r
-              IdeDev,\r
-              (VOID *) TmpAtaIdentifyPointer,\r
-              sizeof (EFI_IDENTIFY_DATA),\r
-              ATA_CMD_IDENTIFY_DRIVE,\r
-              DeviceSelect,\r
-              0,\r
-              0,\r
-              0,\r
-              0\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      gBS->FreePool (TmpAtaIdentifyPointer);\r
-      return ;\r
+    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+      Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+    } else {\r
+      Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     }\r
-\r
+  } else {\r
     //\r
-    // Check if the feature is enabled\r
+    // For ATA-3 compatible device, use ATA-3 read block mechanism\r
     //\r
-    if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {\r
-      //\r
-      // Read status data\r
-      //\r
-      AtaNonDataCommandIn (\r
-        IdeDev,\r
-        ATA_CMD_SMART,\r
-        Device,\r
-        ATA_SMART_RETURN_STATUS,\r
-        0,\r
-        0,\r
-        ATA_CONSTANT_4F,\r
-        ATA_CONSTANT_C2\r
-        );\r
-      LBAMid  = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
-      LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);\r
-\r
-      if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {\r
-        //\r
-        // The threshold exceeded condition is not detected by the device\r
-        //\r
-        REPORT_STATUS_CODE (\r
-              EFI_PROGRESS_CODE,\r
-              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)\r
-              );\r
-\r
-      } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {\r
-        //\r
-        // The threshold exceeded condition is  detected by the device\r
-        //\r
-        REPORT_STATUS_CODE (\r
-              EFI_PROGRESS_CODE,\r
-              (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)\r
-              );\r
-      }\r
-\r
+    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+      Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     } else {\r
-      //\r
-      // Report disabled status code\r
-      //\r
-      REPORT_STATUS_CODE (\r
-            EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-            (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)\r
-            );\r
+      Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     }\r
+  }\r
 \r
-    gBS->FreePool (TmpAtaIdentifyPointer);\r
+  if (EFI_ERROR (Status)) {\r
+    AtaSoftReset (IdeBlkIoDevice);\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  return ;\r
-}\r
+  return EFI_SUCCESS;\r
 \r
+}\r
 /**\r
-  Enable Long Physical Sector Feature for ATA device.\r
+  This function is used to send out ATA commands conforms to the\r
+  PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
 \r
-  @param   IdeDev  The IDE device data\r
+  Comparing with ATA-3 data out protocol, we have two differents here:<BR>\r
+  1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+  wait will frequently fail... cause writing function return error)\r
+\r
+  2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+  slow down writing performance by 100 times!)\r
+\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                       to record all the information of the IDE device.\r
+  @param Buffer       buffer contained data transferred from host to device.\r
+  @param ByteCount    data size in byte unit of the buffer.\r
+  @param AtaCommand   value of the Command Register\r
+  @param StartLba     the start LBA of this transaction\r
+  @param SectorCount  the count of sectors to be transfered\r
+\r
+  @retval EFI_SUCCESS      send out the ATA command and device receive required\r
+                           data successfully.\r
+  @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
-  @retval  EFI_SUCCESS      The ATA device supports Long Physical Sector feature\r
-                            and corresponding fields in BlockIo structure is updated.\r
-  @retval  EFI_UNSUPPORTED  The device is not ATA device or Long Physical Sector\r
-                            feature is not supported.\r
 **/\r
 EFI_STATUS\r
-AtaEnableLongPhysicalSector (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
+AtaPioDataOutExt (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  VOID            *Buffer,\r
+  IN  UINT32          ByteCount,\r
+  IN  UINT8           AtaCommand,\r
+  IN  EFI_LBA         StartLba,\r
+  IN  UINT16          SectorCount\r
   )\r
 {\r
-  EFI_ATA_IDENTIFY_DATA  *AtaIdentifyData;\r
-  UINT16                 PhyLogicSectorSupport;\r
+  UINT8       DevSel;\r
+  UINT8       SectorCount8;\r
+  UINT8       LbaLow;\r
+  UINT8       LbaMid;\r
+  UINT8       LbaHigh;\r
+  UINTN       WordCount;\r
+  UINTN       Increment;\r
+  UINT16      *Buffer16;\r
+  EFI_STATUS  Status;\r
+\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-  ASSERT (IdeDev->IdData != NULL);\r
   //\r
-  // Only valid for ATA device\r
+  // Select device. Set bit6 as 1 to indicate LBA mode is used\r
   //\r
-  AtaIdentifyData       = (EFI_ATA_IDENTIFY_DATA *) &IdeDev->IdData->AtaData;\r
-  if ((AtaIdentifyData->config & 0x8000) != 0) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  PhyLogicSectorSupport = AtaIdentifyData->phy_logic_sector_support;\r
+  DevSel = (UINT8) (IdeDev->Device << 4);\r
+  DevSel |= 0x40;\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    DevSel\r
+    );\r
+\r
   //\r
-  // Check whether Long Physical Sector Feature is supported\r
-  //\r
-  if ((PhyLogicSectorSupport & 0xc000) == 0x4000) {\r
-    IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;\r
-    IdeDev->BlkIo.Media->LowestAlignedLba              = 0;\r
-    //\r
-    // Check whether one physical block contains multiple physical blocks\r
-    //\r
-    if ((PhyLogicSectorSupport & 0x2000) != 0) {\r
-      IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock =\r
-        (UINT32) (1 << (PhyLogicSectorSupport & 0x000f));\r
-      //\r
-      // Check lowest alignment of logical blocks within physical block\r
-      //\r
-      if ((AtaIdentifyData->alignment_logic_in_phy_blocks & 0xc000) == 0x4000) {\r
-        IdeDev->BlkIo.Media->LowestAlignedLba =\r
-          (EFI_LBA) (AtaIdentifyData->alignment_logic_in_phy_blocks & 0x3fff);\r
-      }\r
-    }\r
-    //\r
-    // Check logical block size\r
-    //\r
-    IdeDev->BlkIo.Media->BlockSize = 0x200;\r
-    if ((PhyLogicSectorSupport & 0x1000) != 0) {\r
-      IdeDev->BlkIo.Media->BlockSize = (UINT32) (\r
-        ((AtaIdentifyData->logic_sector_size_hi << 16) |\r
-         AtaIdentifyData->logic_sector_size_lo) * sizeof (UINT16)\r
-        );\r
-    }\r
-    return EFI_SUCCESS;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Send ATA Ext command into device with NON_DATA protocol\r
-\r
-  @param  IdeDev Standard IDE device private data structure\r
-  @param  AtaCommand The ATA command to be sent\r
-  @param  Device The value in Device register\r
-  @param  Feature The value in Feature register\r
-  @param  SectorCount The value in SectorCount register\r
-  @param  LbaAddress The LBA address in 48-bit mode\r
-\r
-  @retval  EFI_SUCCESS Reading succeed\r
-  @retval  EFI_DEVICE_ERROR Error executing commands on this device.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssueExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT16          Feature,\r
-  IN  UINT16          SectorCount,\r
-  IN  EFI_LBA         LbaAddress\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT8       SectorCount8;\r
-  UINT8       Feature8;\r
-  UINT8       LbaLow;\r
-  UINT8       LbaMid;\r
-  UINT8       LbaHigh;\r
-\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
-  //\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
-    );\r
-\r
-  //\r
-  // ATA commands for ATA device must be issued when DRDY is set\r
+  // Wait for DRDY singnal asserting.\r
   //\r
   Status = DRDYReady (IdeDev, ATATIMEOUT);\r
   if (EFI_ERROR (Status)) {\r
@@ -2021,18 +2202,11 @@ AtaCommandIssueExt (
   }\r
 \r
   //\r
-  // Pass parameter into device register block\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
-  //\r
-  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+  // Fill feature register if needed\r
   //\r
-  Feature8 = (UINT8) (Feature >> 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
-  Feature8 = (UINT8) Feature;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+  if (AtaCommand == ATA_CMD_SET_FEATURES) {\r
+    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);\r
+  }\r
 \r
   //\r
   // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
@@ -2046,685 +2220,579 @@ AtaCommandIssueExt (
   //\r
   // Fill the start LBA registers, which are also two-byte FIFO\r
   //\r
-  LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  LbaLow = (UINT8) LbaAddress;\r
+  LbaLow  = (UINT8) RShiftU64 (StartLba, 24);\r
+  LbaMid  = (UINT8) RShiftU64 (StartLba, 32);\r
+  LbaHigh = (UINT8) RShiftU64 (StartLba, 40);\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-\r
-  LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-\r
-  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
-  //\r
-  // Work around for Segate 160G disk writing\r
-  //\r
-  gBS->Stall (1800);\r
+  LbaLow  = (UINT8) StartLba;\r
+  LbaMid  = (UINT8) RShiftU64 (StartLba, 8);\r
+  LbaHigh = (UINT8) RShiftU64 (StartLba, 16);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
 \r
   //\r
-  // Send command via Command Register\r
+  // Send command via Command Register, invoking the processing of this command\r
   //\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
 \r
-  //\r
-  // Stall at least 400ns\r
-  //\r
-  gBS->Stall (100);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Send ATA Ext command into device with NON_DATA protocol\r
-\r
-  @param  IdeDev Standard IDE device private data structure\r
-  @param  AtaCommand The ATA command to be sent\r
-  @param  Device The value in Device register\r
-  @param  Feature The value in Feature register\r
-  @param  SectorCount The value in SectorCount register\r
-  @param  LbaAddress The LBA address in 48-bit mode\r
-\r
-  @retval  EFI_SUCCESS Reading succeed\r
-  @retval  EFI_DEVICE_ERROR Error executing commands on this device.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssue (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT16          Feature,\r
-  IN  UINT16          SectorCount,\r
-  IN  EFI_LBA         LbaAddress\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT8       SectorCount8;\r
-  UINT8       Feature8;\r
-  UINT8       Lba0;\r
-  UINT8       Lba1;\r
-  UINT8       Lba2;\r
-  UINT8       Lba3;\r
-\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
-  //\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
-    );\r
-\r
-  //\r
-  // ATA commands for ATA device must be issued when DRDY is set\r
-  //\r
-  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Lba0  = (UINT8) LbaAddress;\r
-  Lba1  = (UINT8) RShiftU64 (LbaAddress, 8);\r
-  Lba2  = (UINT8) RShiftU64 (LbaAddress, 16);\r
-  Lba3  = (UINT8) RShiftU64 (LbaAddress, 24);\r
-  Device = (UINT8) (Device | Lba3);\r
+  Buffer16 = (UINT16 *) Buffer;\r
 \r
   //\r
-  // Pass parameter into device register block\r
+  // According to PIO Data Out protocol, host can perform a series of writes to\r
+  // the data register after each time device set DRQ ready;\r
   //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+  Increment = 256;\r
 \r
   //\r
-  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+  // used to record bytes of currently transfered data\r
   //\r
-  Feature8 = (UINT8) Feature;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+  WordCount = 0;\r
 \r
-  //\r
-  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
-  //\r
-  SectorCount8 = (UINT8) SectorCount;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+  while (WordCount < ByteCount / 2) {\r
+    //\r
+    // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.\r
+    //\r
+    Status = DRQReady2 (IdeDev, ATATIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
 \r
-  //\r
-  // Fill the start LBA registers, which are also two-byte FIFO\r
-  //\r
+    Status = CheckErrorStatus (IdeDev);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
 \r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);\r
+    //\r
+    // Write data into device by one series of writing to data register\r
+    //\r
+    if ((WordCount + Increment) > ByteCount / 2) {\r
+      Increment = ByteCount / 2 - WordCount;\r
+    }\r
 \r
-  //\r
-  // Send command via Command Register\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+    IDEWritePortWMultiple (\r
+      IdeDev->PciIo,\r
+      IdeDev->IoPort->Data,\r
+      Increment,\r
+      Buffer16\r
+      );\r
 \r
-  //\r
-  // Stall at least 400ns\r
-  //\r
-  gBS->Stall (100);\r
+    WordCount += Increment;\r
+    Buffer16 += Increment;\r
 \r
-  return EFI_SUCCESS;\r
+  }\r
+  return CheckErrorStatus (IdeDev);\r
 }\r
-\r
 /**\r
-  This function is called by the AtaBlkIoReadBlocks() to perform\r
-  reading from media in block unit. The function has been enhanced to\r
+  This function is called by the AtaBlkIoWriteBlocks() to perform\r
+  writing to media in block unit. The function has been enhanced to\r
   support >120GB access and transfer at most 65536 blocks per command\r
 \r
-  @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
-\r
-  @param[in] StartLba The starting logical block address to read from\r
-  on the device media.\r
-\r
-  @param[in] NumberOfBlocks The number of transfer data blocks.\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                        to record all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the source buffer for the data.\r
+  @param StartLba       The starting logical block address to write to\r
+                        on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
 \r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
-\r
-  TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+  @return status depends on the function DoAtaUdma() returns.\r
 **/\r
 EFI_STATUS\r
-AtaUdmaReadExt (\r
+AtaUdmaWriteExt (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  VOID            *DataBuffer,\r
   IN  EFI_LBA         StartLba,\r
   IN  UINTN           NumberOfBlocks\r
   )\r
 {\r
-  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);\r
+  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);\r
 }\r
 \r
 /**\r
-  This function is called by the AtaBlkIoReadBlocks() to perform\r
-  reading from media in block unit. The function has been enhanced to\r
-  support >120GB access and transfer at most 65536 blocks per command\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer    A pointer to the destination buffer for the data.\r
-  @param[in] StartLba       The starting logical block address to read from\r
-  on the device media.\r
-  @param[in] NumberOfBlocks The number of transfer data blocks.\r
-\r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
-\r
-  TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+  This function is called by the AtaBlkIoWriteBlocks() to perform\r
+  writing to media in block unit. \r
+\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                        to record all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the source buffer for the data.\r
+  @param StartLba       The starting logical block address to write to\r
+                        on the device media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
+  \r
+  @return status depends on the function DoAtaUdma() returns.\r
 **/\r
 EFI_STATUS\r
-AtaUdmaRead (\r
+AtaUdmaWrite (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  VOID            *DataBuffer,\r
   IN  EFI_LBA         StartLba,\r
   IN  UINTN           NumberOfBlocks\r
   )\r
 {\r
-  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);\r
+  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);\r
 }\r
-\r
 /**\r
   This function is called by the AtaBlkIoWriteBlocks() to perform\r
-  writing to media in block unit. The function has been enhanced to\r
+  writing onto media in block unit. The function has been enhanced to\r
   support >120GB access and transfer at most 65536 blocks per command\r
 \r
-  @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer A pointer to the source buffer for the data.\r
-\r
-  @param[in] StartLba The starting logical block address to write to\r
-  on the device media.\r
-\r
-  @param[in] NumberOfBlocks The number of transfer data blocks.\r
+  @param IdeDev         pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+                        to record all the information of the IDE device.\r
+  @param DataBuffer     A pointer to the source buffer for the data.\r
+  @param StartLba       The starting logical block address to write onto the device \r
+                        media.\r
+  @param NumberOfBlocks The number of transfer data blocks.\r
 \r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
-\r
-  TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+  @return status is fully dependent on the return status of AtaPioDataOutExt() function.\r
 **/\r
 EFI_STATUS\r
-AtaUdmaWriteExt (\r
+AtaWriteSectorsExt (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  VOID            *DataBuffer,\r
   IN  EFI_LBA         StartLba,\r
   IN  UINTN           NumberOfBlocks\r
   )\r
 {\r
-  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);\r
-}\r
+  EFI_STATUS  Status;\r
+  EFI_LBA     Lba64;\r
+  UINTN       BlocksRemaining;\r
+  UINT8       AtaCommand;\r
+  UINT16      SectorCount;\r
+  UINT32      ByteCount;\r
+  VOID        *Buffer;\r
 \r
-/**\r
-  This function is called by the AtaBlkIoWriteBlocks() to perform\r
-  writing to media in block unit. The function has been enhanced to\r
-  support >120GB access and transfer at most 65536 blocks per command\r
+  //\r
+  // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol\r
+  //\r
+  AtaCommand      = ATA_CMD_WRITE_SECTORS_EXT;\r
+  Lba64           = StartLba;\r
+  Buffer          = DataBuffer;\r
+  BlocksRemaining = NumberOfBlocks;\r
+\r
+  Status          = EFI_SUCCESS;\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  while (BlocksRemaining > 0) {\r
 \r
-  @param[in] *DataBuffer\r
-  A pointer to the source buffer for the data.\r
+    if (BlocksRemaining >= 0x10000) {\r
+      //\r
+      //  SectorCount is used to record the number of sectors to be written.\r
+      //  Max 65536 sectors can be transfered at a time.\r
+      //\r
+      SectorCount = 0xffff;\r
+    } else {\r
+      SectorCount = (UINT16) BlocksRemaining;\r
+    }\r
 \r
-  @param[in] StartLba\r
-  The starting logical block address to write to\r
-  on the device media.\r
+    //\r
+    // ByteCount is the number of bytes that will be written\r
+    //\r
+    ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);\r
 \r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
+    //\r
+    // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command\r
+    //\r
+    Status = AtaPioDataOutExt (\r
+              IdeDev,\r
+              Buffer,\r
+              ByteCount,\r
+              AtaCommand,\r
+              Lba64,\r
+              SectorCount\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
+    Lba64 += SectorCount;\r
+    Buffer = ((UINT8 *) Buffer + ByteCount);\r
+    BlocksRemaining -= SectorCount;\r
+  }\r
 \r
-  TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-  TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWrite (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  )\r
-{\r
-  return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);\r
+  return Status;\r
 }\r
-\r
 /**\r
-  Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer\r
-  A pointer to the source buffer for the data.\r
-\r
-  @param[in] StartLba\r
-  The starting logical block address to write to\r
-  on the device media.\r
+  This function is the ATA implementation for WriteBlocks in the\r
+  Block I/O Protocol interface.\r
 \r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
+  @param IdeBlkIoDevice  Indicates the calling context.\r
+  @param MediaId         The media id that the write request is for.\r
+  @param LBA             The starting logical block address to write onto the device.\r
+  @param BufferSize      The size of the Buffer in bytes. This must be a multiple\r
+                         of the intrinsic block size of the device.\r
+  @param Buffer          A pointer to the source buffer for the data.The caller\r
+                         is responsible for either having implicit or explicit \r
+                         ownership of the memory that data is written from.\r
 \r
-  @param[in] UdmaOp\r
-  The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
-  AtaUdmaWriteOp, AtaUdmaWriteExOp\r
+  @retval EFI_SUCCESS       Write Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR  Write Blocks failed.\r
+  @retval EFI_NO_MEDIA      There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE  The MediaId is not for the current media.\r
 \r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
+                                or the data buffer is not valid.\r
 \r
+  @note If Write Block error because of device error, this function will call\r
+        AtaSoftReset() function to reset device.\r
 **/\r
 EFI_STATUS\r
-DoAtaUdma (\r
-  IN  IDE_BLK_IO_DEV      *IdeDev,\r
-  IN  VOID                *DataBuffer,\r
-  IN  EFI_LBA             StartLba,\r
-  IN  UINTN               NumberOfBlocks,\r
-  IN  ATA_UDMA_OPERATION  UdmaOp\r
+AtaBlkIoWriteBlocks (\r
+  IN  IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
+  IN  UINT32           MediaId,\r
+  IN  EFI_LBA          LBA,\r
+  IN  UINTN            BufferSize,\r
+  OUT VOID             *Buffer\r
   )\r
 {\r
-  IDE_DMA_PRD                   *PrdAddr;\r
-  IDE_DMA_PRD                   *UsedPrdAddr;\r
-  IDE_DMA_PRD                   *TempPrdAddr;\r
-  UINT8                         RegisterValue;\r
-  UINT8                         Device;\r
-  UINT64                        IoPortForBmic;\r
-  UINT64                        IoPortForBmis;\r
-  UINT64                        IoPortForBmid;\r
-  EFI_STATUS                    Status;\r
-  UINTN                         PrdTableNum;\r
-  UINTN                         ByteCount;\r
-  UINTN                         ByteAvailable;\r
-  UINT8                         *PrdBuffer;\r
-  UINTN                         RemainBlockNum;\r
-  UINT8                         DeviceControl;\r
-  UINT32                        Count;\r
-  UINTN                         PageCount;\r
-  VOID                          *Map;\r
-  VOID                          *MemPage;\r
-  EFI_PHYSICAL_ADDRESS          DeviceAddress;\r
-  UINTN                         MaxDmaCommandSectors;\r
-  EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;\r
-  UINT8                         AtaCommand;\r
 \r
-  switch (UdmaOp) {\r
-  case AtaUdmaReadOp:\r
-    MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
-    PciIoProtocolOp      = EfiPciIoOperationBusMasterWrite;\r
-    AtaCommand           = ATA_CMD_READ_DMA;\r
-    break;\r
-  case AtaUdmaReadExtOp:\r
-    MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
-    PciIoProtocolOp      = EfiPciIoOperationBusMasterWrite;\r
-    AtaCommand           = ATA_CMD_READ_DMA_EXT;\r
-    break;\r
-  case AtaUdmaWriteOp:\r
-    MaxDmaCommandSectors = ATAPI_MAX_DMA_CMD_SECTORS;\r
-    PciIoProtocolOp      = EfiPciIoOperationBusMasterRead;\r
-    AtaCommand           = ATA_CMD_WRITE_DMA;\r
-    break;\r
-  case AtaUdmaWriteExtOp:\r
-    MaxDmaCommandSectors = ATAPI_MAX_DMA_EXT_CMD_SECTORS;\r
-    PciIoProtocolOp      = EfiPciIoOperationBusMasterRead;\r
-    AtaCommand           = ATA_CMD_WRITE_DMA_EXT;\r
-    break;\r
-  default:\r
-    return EFI_UNSUPPORTED;\r
-    break;\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  UINTN               BlockSize;\r
+  UINTN               NumberOfBlocks;\r
+  EFI_STATUS          Status;\r
+\r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Select device\r
-  //\r
-  Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+  if (BufferSize == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   //\r
-  // Enable interrupt to support UDMA\r
+  // Get the intrinsic block size\r
   //\r
-  DeviceControl = 0;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+  Media           = IdeBlkIoDevice->BlkIo.Media;\r
+  BlockSize       = Media->BlockSize;\r
+  NumberOfBlocks  = BufferSize / BlockSize;\r
 \r
-  if (IdePrimary == IdeDev->Channel) {\r
-    IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;\r
-    IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
-    IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;\r
-  } else {\r
-    if (IdeSecondary == IdeDev->Channel) {\r
-      IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;\r
-      IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
-      IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;\r
-    } else {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
+  if (MediaId != Media->MediaId) {\r
+    return EFI_MEDIA_CHANGED;\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
+  if (BufferSize % BlockSize != 0) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
 \r
-  Status = EFI_SUCCESS;\r
-  \r
-  RemainBlockNum = NumberOfBlocks;\r
-  while (RemainBlockNum > 0) {\r
+  if (LBA > Media->LastBlock) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-    if (RemainBlockNum >= MaxDmaCommandSectors) {\r
-      //\r
-      //  SectorCount is used to record the number of sectors to be read\r
-      //  Max 65536 sectors can be transfered at a time.\r
-      //\r
-      NumberOfBlocks = MaxDmaCommandSectors;\r
-      RemainBlockNum -= MaxDmaCommandSectors;\r
-    } else {\r
-      NumberOfBlocks  = (UINT16) RemainBlockNum;\r
-      RemainBlockNum  = 0;\r
-    }\r
+  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-    //\r
-    // Calculate the number of PRD table to make sure the memory region\r
-    // not cross 64K boundary\r
-    //\r
-    ByteCount   = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
-    PrdTableNum = ((ByteCount >> 16) + 1) + 1;\r
+  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
+  Status = EFI_SUCCESS;\r
+  if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
     //\r
-    // Build PRD table\r
+    // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism\r
     //\r
-    PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
-    Status = IdeDev->PciIo->AllocateBuffer (\r
-                    IdeDev->PciIo,\r
-                    AllocateAnyPages,\r
-                    EfiBootServicesData,\r
-                    PageCount,\r
-                    &MemPage,\r
-                    0\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
-\r
-    PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
-    //\r
-    // To make sure PRD is allocated in one 64K page\r
-    //\r
-    if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {\r
-      UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);\r
+    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+      Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     } else {\r
-      if ((UINTN) PrdAddr & 0x03) {\r
-        UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);\r
-      } else {\r
-        UsedPrdAddr = PrdAddr;\r
-      }\r
+      Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     }\r
-\r
+  } else {\r
     //\r
-    // Build the PRD table\r
+    // For ATA-3 compatible device, use ATA-3 write block mechanism\r
     //\r
-    Status = IdeDev->PciIo->Map (\r
-                       IdeDev->PciIo,\r
-                       PciIoProtocolOp,\r
-                       DataBuffer,\r
-                       &ByteCount,\r
-                       &DeviceAddress,\r
-                       &Map\r
-                       );\r
-    if (EFI_ERROR (Status)) {\r
-      IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
-      return EFI_OUT_OF_RESOURCES;\r
+    if (IdeBlkIoDevice->UdmaMode.Valid) {\r
+      Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+    } else {\r
+      Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
     }\r
-    PrdBuffer   = (VOID *) ((UINTN) DeviceAddress);\r
-    TempPrdAddr = UsedPrdAddr;\r
-    while (TRUE) {\r
+  }\r
 \r
-      ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);\r
+  if (EFI_ERROR (Status)) {\r
+    AtaSoftReset (IdeBlkIoDevice);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-      if (ByteCount <= ByteAvailable) {\r
-        TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
-        TempPrdAddr->ByteCount      = (UINT16) ByteCount;\r
-        TempPrdAddr->EndOfTable     = 0x8000;\r
-        break;\r
-      }\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  Enable Long Physical Sector Feature for ATA device.\r
 \r
-      TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);\r
-      TempPrdAddr->ByteCount      = (UINT16) ByteAvailable;\r
+  @param   IdeDev  The IDE device data\r
 \r
-      ByteCount -= ByteAvailable;\r
-      PrdBuffer += ByteAvailable;\r
-      TempPrdAddr++;\r
-    }\r
+  @retval  EFI_SUCCESS      The ATA device supports Long Physical Sector feature\r
+                            and corresponding fields in BlockIo structure is updated.\r
+  @retval  EFI_UNSUPPORTED  The device is not ATA device or Long Physical Sector\r
+                            feature is not supported.\r
+**/\r
+EFI_STATUS\r
+AtaEnableLongPhysicalSector (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev\r
+  )\r
+{\r
+  EFI_ATA_IDENTIFY_DATA  *AtaIdentifyData;\r
+  UINT16                 PhyLogicSectorSupport;\r
 \r
+  ASSERT (IdeDev->IdData != NULL);\r
+  //\r
+  // Only valid for ATA device\r
+  //\r
+  AtaIdentifyData       = (EFI_ATA_IDENTIFY_DATA *) &IdeDev->IdData->AtaData;\r
+  if ((AtaIdentifyData->config & 0x8000) != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  PhyLogicSectorSupport = AtaIdentifyData->phy_logic_sector_support;\r
+  //\r
+  // Check whether Long Physical Sector Feature is supported\r
+  //\r
+  if ((PhyLogicSectorSupport & 0xc000) == 0x4000) {\r
+    IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;\r
+    IdeDev->BlkIo.Media->LowestAlignedLba              = 0;\r
     //\r
-    // Set the base address to BMID register\r
+    // Check whether one physical block contains multiple physical blocks\r
     //\r
-    IdeDev->PciIo->Io.Write (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint32,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmid,\r
-                        1,\r
-                        &UsedPrdAddr\r
-                        );\r
-\r
+    if ((PhyLogicSectorSupport & 0x2000) != 0) {\r
+      IdeDev->BlkIo.Media->LogicalBlocksPerPhysicalBlock =\r
+        (UINT32) (1 << (PhyLogicSectorSupport & 0x000f));\r
+      //\r
+      // Check lowest alignment of logical blocks within physical block\r
+      //\r
+      if ((AtaIdentifyData->alignment_logic_in_phy_blocks & 0xc000) == 0x4000) {\r
+        IdeDev->BlkIo.Media->LowestAlignedLba =\r
+          (EFI_LBA) (AtaIdentifyData->alignment_logic_in_phy_blocks & 0x3fff);\r
+      }\r
+    }\r
     //\r
-    // Set BMIC register to identify the operation direction\r
+    // Check logical block size\r
     //\r
-    IdeDev->PciIo->Io.Read (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
-\r
-    if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {\r
-      RegisterValue |= BMIC_NREAD;\r
-    } else {\r
-      RegisterValue &= ~((UINT8) BMIC_NREAD);\r
+    IdeDev->BlkIo.Media->BlockSize = 0x200;\r
+    if ((PhyLogicSectorSupport & 0x1000) != 0) {\r
+      IdeDev->BlkIo.Media->BlockSize = (UINT32) (\r
+        ((AtaIdentifyData->logic_sector_size_hi << 16) |\r
+         AtaIdentifyData->logic_sector_size_lo) * sizeof (UINT16)\r
+        );\r
     }\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+}\r
+/**\r
+  Send ATA command into device with NON_DATA protocol\r
 \r
-    IdeDev->PciIo->Io.Write (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaLow The value in LBA_LOW register\r
+  @param  LbaMiddle The value in LBA_MIDDLE register\r
+  @param  LbaHigh The value in LBA_HIGH register\r
 \r
-    if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {\r
-      Status = AtaCommandIssueExt (\r
-                 IdeDev,\r
-                 AtaCommand,\r
-                 Device,\r
-                 0,\r
-                 (UINT16) NumberOfBlocks,\r
-                 StartLba\r
-                 );\r
-    } else {\r
-      Status = AtaCommandIssue (\r
-                 IdeDev,\r
-                 AtaCommand,\r
-                 Device,\r
-                 0,\r
-                 (UINT16) NumberOfBlocks,\r
-                 StartLba\r
-                 );\r
-    }\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_ABORTED Command failed\r
+  @retval  EFI_DEVICE_ERROR Device status error.\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
-      IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandIn (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  UINT8           AtaCommand,\r
+  IN  UINT8           Device,\r
+  IN  UINT8           Feature,\r
+  IN  UINT8           SectorCount,\r
+  IN  UINT8           LbaLow,\r
+  IN  UINT8           LbaMiddle,\r
+  IN  UINT8           LbaHigh\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       StatusRegister;\r
 \r
-    //\r
-    // Set START bit of BMIC register\r
-    //\r
-    IdeDev->PciIo->Io.Read (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-    RegisterValue |= BMIC_START;\r
+  //\r
+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
+  //\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+    );\r
 \r
-    IdeDev->PciIo->Io.Write (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
+  //\r
+  // ATA commands for ATA device must be issued when DRDY is set\r
+  //\r
+  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-    //\r
-    // Check the INTERRUPT and ERROR bit of BMIS\r
-    // Max transfer number of sectors for one command is 65536(32Mbyte),\r
-    // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
-    // So set the variable Count to 2000, for about 2 second timeout time.\r
-    //\r
-    Status = EFI_SUCCESS;\r
-    Count = 2000;\r
-    while (TRUE) {\r
+  //\r
+  // Pass parameter into device register block\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\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
-      if (((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) != 0) || (Count == 0)) {\r
-        if (((RegisterValue & BMIS_ERROR) != 0) || (Count == 0)) {\r
-                 Status = EFI_DEVICE_ERROR;\r
-                 break;\r
-        }\r
-        break;\r
-      }\r
+  //\r
+  // Send command via Command Register\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
 \r
-      gBS->Stall (1000);\r
-      Count --;\r
-    }\r
+  //\r
+  // Wait for command completion\r
+  // For ATAPI_SMART_CMD, we may need more timeout to let device\r
+  // adjust internal states.\r
+  //\r
+  if (AtaCommand == ATA_CMD_SMART) {\r
+    Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT);\r
+  } else {\r
+    Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-    IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
-    IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
+  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+  if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
     //\r
-    // Read BMIS register and clear ERROR and INTR bit\r
+    // Failed to execute command, abort operation\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
+    return EFI_ABORTED;\r
+  }\r
 \r
-    RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
+  return EFI_SUCCESS;\r
+}\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
-    // Read Status Register of IDE device to clear interrupt\r
-    //\r
-    RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
-    //\r
-    // Clear START bit of BMIC register\r
-    //\r
-    IdeDev->PciIo->Io.Read (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
+/**\r
+  Send ATA Ext command into device with NON_DATA protocol\r
 \r
-    RegisterValue &= ~((UINT8) BMIC_START);\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaAddress The LBA address in 48-bit mode\r
 \r
-    IdeDev->PciIo->Io.Write (\r
-                        IdeDev->PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                        IoPortForBmic,\r
-                        1,\r
-                        &RegisterValue\r
-                        );\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_ABORTED Command failed\r
+  @retval  EFI_DEVICE_ERROR Device status error.\r
 \r
-    if ((RegisterValue & BMIS_ERROR) != 0) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
+**/\r
+EFI_STATUS\r
+AtaNonDataCommandInExt (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  UINT8           AtaCommand,\r
+  IN  UINT8           Device,\r
+  IN  UINT16          Feature,\r
+  IN  UINT16          SectorCount,\r
+  IN  EFI_LBA         LbaAddress\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       StatusRegister;\r
+  UINT8       SectorCount8;\r
+  UINT8       Feature8;\r
+  UINT8       LbaLow;\r
+  UINT8       LbaMid;\r
+  UINT8       LbaHigh;\r
 \r
-       if (EFI_ERROR (Status)) {\r
-         break;\r
-       }\r
-    DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
-    StartLba += NumberOfBlocks;\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   //\r
-  // Disable interrupt of Select device\r
+  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
   //\r
-  IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
-  DeviceControl |= ATA_CTLREG_IEN_L;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+  IDEWritePortB (\r
+    IdeDev->PciIo,\r
+    IdeDev->IoPort->Head,\r
+    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
+    );\r
 \r
-  return Status;\r
+  //\r
+  // ATA commands for ATA device must be issued when DRDY is set\r
+  //\r
+  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Pass parameter into device register block\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
+\r
+  //\r
+  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
+  //\r
+  Feature8 = (UINT8) (Feature >> 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+  Feature8 = (UINT8) Feature;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
+\r
+  //\r
+  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
+  //\r
+  SectorCount8 = (UINT8) (SectorCount >> 8);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+  SectorCount8 = (UINT8) SectorCount;\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
+\r
+  //\r
+  // Fill the start LBA registers, which are also two-byte FIFO\r
+  //\r
+  LbaLow  = (UINT8) RShiftU64 (LbaAddress, 24);\r
+  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 32);\r
+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+  LbaLow  = (UINT8) LbaAddress;\r
+  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 8);\r
+  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
+\r
+  //\r
+  // Send command via Command Register\r
+  //\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
+\r
+  //\r
+  // Wait for command completion\r
+  //\r
+  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+  if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
+    //\r
+    // Failed to execute command, abort operation\r
+    //\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
+\r
+\r
index b53f20ee820465ac0f5b963ae7f51ce0033a73a0..74b48d1443658609bbd51cfbc53fd7d9144f447c 100644 (file)
@@ -1,4 +1,6 @@
 /** @file\r
+   This file contains all helper functions on the ATAPI command \r
+  \r
   Copyright (c) 2006 - 2008, Intel Corporation                                                        \r
   All rights reserved. This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
   in the LS-120 drive or ZIP drive. The media status is returned in the \r
   Error Status.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @retval EFI_SUCCESS\r
-  The media status is achieved successfully and the media\r
-  can be read/written.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Get Media Status Command is failed.\r
-  \r
-  @retval EFI_NO_MEDIA\r
-  There is no media in the drive.\r
-  \r
-  @retval EFI_WRITE_PROTECTED\r
-  The media is writing protected.\r
+  @param IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                  to record all the information of the IDE device.\r
 \r
-  @note\r
-  This function must be called after the LS120EnableMediaStatus() \r
-  with second parameter set to TRUE \r
-  (means enable media status notification) is called.\r
+  @retval EFI_SUCCESS         The media status is achieved successfully and the media\r
+                              can be read/written.\r
+  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.\r
+  @retval EFI_NO_MEDIA        There is no media in the drive.\r
+  @retval EFI_WRITE_PROTECTED The media is writing protected.\r
 \r
+  @note  This function must be called after the LS120EnableMediaStatus() \r
+         with second parameter set to TRUE \r
+         (means enable media status notification) is called.\r
 **/\r
 EFI_STATUS\r
 LS120GetMediaStatus (\r
@@ -100,25 +92,17 @@ LS120GetMediaStatus (
     return EFI_SUCCESS;\r
   }\r
 }\r
-\r
 /**\r
   This function is used to send Enable Media Status Notification Command\r
   or Disable Media Status Notification Command.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] Enable\r
-  a flag that indicates whether enable or disable media\r
-  status notification.\r
-\r
-  @retval EFI_SUCCESS\r
-  If command completes successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  If command failed.\r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                to record all the information of the IDE device.\r
 \r
+  @param Enable a flag that indicates whether enable or disable media\r
+                status notification.\r
+  @retval EFI_SUCCESS      If command completes successfully.\r
+  @retval EFI_DEVICE_ERROR If command failed.\r
 **/\r
 EFI_STATUS\r
 LS120EnableMediaStatus (\r
@@ -179,283 +163,184 @@ LS120EnableMediaStatus (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
-  This function is called by DiscoverIdeDevice() during its device\r
-  identification.\r
-\r
-  Its main purpose is to get enough information for the device media\r
-  to fill in the Media data structure of the Block I/O Protocol interface.\r
-\r
-  There are 5 steps to reach such objective:\r
-\r
-  1. Sends out the ATAPI Identify Command to the specified device. \r
-  Only ATAPI device responses to this command. If the command succeeds,\r
-  it returns the Identify data structure which filled with information \r
-  about the device. Since the ATAPI device contains removable media, \r
-  the only meaningful information is the device module name.\r
-\r
-  2. Sends out ATAPI Inquiry Packet Command to the specified device.\r
-  This command will return inquiry data of the device, which contains\r
-  the device type information.\r
+  This function reads the pending data in the device.\r
 \r
-  3. Allocate sense data space for future use. We don't detect the media\r
-  presence here to improvement boot performance, especially when CD \r
-  media is present. The media detection will be performed just before\r
-  each BLK_IO read/write\r
+  @param IdeDev   Indicates the calling context.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @retval EFI_SUCCESS   Successfully read.\r
+  @retval EFI_NOT_READY The BSY is set avoiding reading.\r
 \r
-  @retval EFI_SUCCESS\r
-  Identify ATAPI device successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  ATAPI Identify Device Command failed or device type\r
-  is not supported by this IDE driver.\r
+**/\r
+EFI_STATUS\r
+AtapiReadPendingData (\r
+  IN IDE_BLK_IO_DEV     *IdeDev\r
+  )\r
+{\r
+  UINT8     AltRegister;\r
+  UINT16    TempWordBuffer;\r
 \r
-  @note\r
-  Parameter "IdeDev" will be updated in this function.\r
+  AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
+  if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {\r
+    return EFI_NOT_READY;\r
+  }\r
+  if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+    TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
+    while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
+      IDEReadPortWMultiple (\r
+        IdeDev->PciIo,\r
+        IdeDev->IoPort->Data, \r
+        1, \r
+        &TempWordBuffer\r
+        );\r
+      TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
 \r
-  TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
-  TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
+/**\r
+  This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut(). \r
+  It is used to transfer data between host and device. The data direction is specified\r
+  by the fourth parameter.\r
+\r
+  @param IdeDev     pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                    all the information of the IDE device.\r
+  @param Buffer     buffer contained data transferred between host and device.\r
+  @param ByteCount  data size in byte unit of the buffer.\r
+  @param Read       flag used to determine the data transfer direction.\r
+                    Read equals 1, means data transferred from device to host;\r
+                    Read equals 0, means data transferred from host to device.\r
+  @param TimeOut    timeout value for wait DRQ ready before each data stream's transfer.\r
+\r
+  @retval EFI_SUCCESS      data is transferred successfully.\r
+  @retval EFI_DEVICE_ERROR the device failed to transfer data.\r
 **/\r
 EFI_STATUS\r
-ATAPIIdentify (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
+PioReadWriteData (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  IN  UINT16          *Buffer,\r
+  IN  UINT32          ByteCount,\r
+  IN  BOOLEAN         Read,\r
+  IN  UINTN           TimeOut\r
   )\r
 {\r
-  EFI_IDENTIFY_DATA *AtapiIdentifyPointer;\r
-  UINT8             DeviceSelect;\r
-  EFI_STATUS        Status;\r
-\r
   //\r
-  // device select bit\r
+  // required transfer data in word unit.\r
   //\r
-  DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);\r
+  UINT32      RequiredWordCount;\r
 \r
-  AtapiIdentifyPointer  = AllocatePool (sizeof (EFI_IDENTIFY_DATA));\r
-  if (AtapiIdentifyPointer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
   //\r
-  // Send ATAPI Identify Command to get IDENTIFY data.\r
+  // actual transfer data in word unit.\r
   //\r
-  Status = AtaPioDataIn (\r
-            IdeDev,\r
-            (VOID *) AtapiIdentifyPointer,\r
-            sizeof (EFI_IDENTIFY_DATA),\r
-            ATA_CMD_IDENTIFY_DEVICE,\r
-            DeviceSelect,\r
-            0,\r
-            0,\r
-            0,\r
-            0\r
-            );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (AtapiIdentifyPointer);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  IdeDev->IdData = AtapiIdentifyPointer;\r
-  PrintAtaModuleName (IdeDev);\r
+  UINT32      ActualWordCount;\r
+  UINT32      WordCount;\r
+  EFI_STATUS  Status;\r
+  UINT16      *PtrBuffer;\r
 \r
   //\r
-  // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
+  // No data transfer is premitted.\r
   //\r
-  Status = AtapiInquiry (IdeDev);\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (IdeDev->IdData);\r
-    //\r
-    // Make sure the pIdData will not be freed again.\r
-    //\r
-    IdeDev->IdData = NULL;\r
-    return EFI_DEVICE_ERROR;\r
+  if (ByteCount == 0) {\r
+    return EFI_SUCCESS;\r
   }\r
   //\r
-  // Get media removable info from INQUIRY data.\r
-  //\r
-  IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80);\r
-\r
-  //\r
-  // Identify device type via INQUIRY data.\r
-  //\r
-  switch (IdeDev->InquiryData->peripheral_type & 0x1f) {\r
-\r
+  // for performance, we assert the ByteCount is an even number\r
+  // which is actually a resonable assumption  \r
+  ASSERT((ByteCount%2) == 0);\r
+  \r
+  PtrBuffer         = Buffer;\r
+  RequiredWordCount = ByteCount / 2;\r
   //\r
-  // Magnetic Disk\r
+  // ActuralWordCount means the word count of data really transferred.\r
   //\r
-  case 0x00:\r
+  ActualWordCount = 0;\r
 \r
+  while (ActualWordCount < RequiredWordCount) {\r
+    \r
     //\r
-    // device is LS120 or ZIP drive.\r
+    // before each data transfer stream, the host should poll DRQ bit ready,\r
+    // to see whether indicates device is ready to transfer data.\r
     //\r
-    IdeDev->Type = IdeMagnetic;\r
-\r
-    IdeDev->BlkIo.Media->MediaId      = 0;\r
+    Status = DRQReady2 (IdeDev, TimeOut);\r
+    if (EFI_ERROR (Status)) {\r
+      return CheckErrorStatus (IdeDev);\r
+    }\r
+    \r
     //\r
-    // Give initial value\r
+    // read Status Register will clear interrupt\r
     //\r
-    IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
-\r
-    IdeDev->BlkIo.Media->LastBlock  = 0;\r
-    IdeDev->BlkIo.Media->BlockSize  = 0x200;\r
-    break;\r
-\r
-  //\r
-  // CD-ROM\r
-  //\r
-  case 0x05:\r
+    IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
 \r
-    IdeDev->Type                      = IdeCdRom;\r
-    IdeDev->BlkIo.Media->MediaId      = 0;\r
     //\r
-    // Give initial value\r
+    // get current data transfer size from Cylinder Registers.\r
     //\r
-    IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+    WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;\r
+    WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
+    WordCount = WordCount & 0xffff;\r
+    WordCount /= 2;\r
 \r
-    IdeDev->BlkIo.Media->LastBlock  = 0;\r
-    IdeDev->BlkIo.Media->BlockSize  = 0x800;\r
-    IdeDev->BlkIo.Media->ReadOnly   = TRUE;\r
-    break;\r
+    WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
 \r
-  //\r
-  // Tape\r
-  //\r
-  case 0x01:\r
+    if (Read) {\r
+      IDEReadPortWMultiple (\r
+        IdeDev->PciIo,\r
+        IdeDev->IoPort->Data,\r
+        WordCount,\r
+        PtrBuffer\r
+        );\r
+    } else {\r
+      IDEWritePortWMultiple (\r
+        IdeDev->PciIo,\r
+        IdeDev->IoPort->Data,\r
+        WordCount,\r
+        PtrBuffer\r
+        );\r
+    }\r
 \r
-  //\r
-  // WORM\r
-  //\r
-  case 0x04:\r
+    PtrBuffer += WordCount;\r
+    ActualWordCount += WordCount;\r
+  }\r
   \r
-  //\r
-  // Optical\r
-  //\r
-  case 0x07:\r
-\r
-  default:\r
-    IdeDev->Type = IdeUnknown;\r
-    gBS->FreePool (IdeDev->IdData);\r
-    gBS->FreePool (IdeDev->InquiryData);\r
+  if (Read) {\r
     //\r
-    // Make sure the pIdData and pInquiryData will not be freed again.\r
+    // In the case where the drive wants to send more data than we need to read,\r
+    // the DRQ bit will be set and cause delays from DRQClear2().\r
+    // We need to read data from the drive until it clears DRQ so we can move on.\r
     //\r
-    IdeDev->IdData       = NULL;\r
-    IdeDev->InquiryData  = NULL;\r
-    return EFI_DEVICE_ERROR;\r
+    AtapiReadPendingData (IdeDev);\r
   }\r
 \r
   //\r
-  // original sense data numbers\r
+  // After data transfer is completed, normally, DRQ bit should clear.\r
   //\r
-  IdeDev->SenseDataNumber = 20;\r
-\r
-  IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));\r
-  if (IdeDev->SenseData == NULL) {\r
-    gBS->FreePool (IdeDev->IdData);\r
-    gBS->FreePool (IdeDev->InquiryData);\r
-    //\r
-    // Make sure the pIdData and pInquiryData will not be freed again.\r
-    //\r
-    IdeDev->IdData       = NULL;\r
-    IdeDev->InquiryData  = NULL;\r
-    return EFI_OUT_OF_RESOURCES;\r
+  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // read status register to check whether error happens.\r
+  //\r
+  return CheckErrorStatus (IdeDev);\r
 }\r
 \r
 /**\r
-  Sends out ATAPI Inquiry Packet Command to the specified device.\r
-  This command will return INQUIRY data of the device.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @retval EFI_SUCCESS\r
-  Inquiry command completes successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Inquiry command failed.\r
-\r
-  @note\r
-  Parameter "IdeDev" will be updated in this function.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiInquiry (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  )\r
-{\r
-  ATAPI_PACKET_COMMAND  Packet;\r
-  EFI_STATUS            Status;\r
-  ATAPI_INQUIRY_DATA          *InquiryData;\r
-\r
-  //\r
-  // prepare command packet for the ATAPI Inquiry Packet Command.\r
-  //\r
-  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
-  Packet.Inquiry.opcode             = ATA_CMD_INQUIRY;\r
-  Packet.Inquiry.page_code          = 0;\r
-  Packet.Inquiry.allocation_length  = sizeof (ATAPI_INQUIRY_DATA);\r
-\r
-  InquiryData                       = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));\r
-  if (InquiryData == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Send command packet and get requested Inquiry data.\r
-  //\r
-  Status = AtapiPacketCommandIn (\r
-            IdeDev,\r
-            &Packet,\r
-            (UINT16 *) InquiryData,\r
-            sizeof (ATAPI_INQUIRY_DATA),\r
-            ATAPITIMEOUT\r
-            );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (InquiryData);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  IdeDev->InquiryData = InquiryData;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function is used to send out ATAPI commands conforms to the \r
-  Packet Command with PIO Data In Protocol.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *Packet\r
-  pointer pointing to ATAPI_PACKET_COMMAND data structure\r
-  which contains the contents of the command.     \r
-\r
-  @param[in] *Buffer\r
-  buffer contained data transferred from device to host.\r
-\r
-  @param[in] ByteCount\r
-  data size in byte unit of the buffer.\r
-\r
-  @param[in] TimeOut\r
-  this parameter is used to specify the timeout \r
-  value for the PioReadWriteData() function. \r
-\r
-  @retval EFI_SUCCESS\r
-  send out the ATAPI packet command successfully\r
-  and device sends data successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  the device failed to send data.\r
+  This function is used to send out ATAPI commands conforms to the Packet Command \r
+  with PIO Data In Protocol.\r
+\r
+  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param Packet    pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+                   which contains the contents of the command.     \r
+  @param Buffer    buffer contained data transferred from device to host.\r
+  @param ByteCount data size in byte unit of the buffer.\r
+  @param TimeOut   this parameter is used to specify the timeout value for the \r
+                   PioReadWriteData() function. \r
+\r
+  @retval EFI_SUCCESS       send out the ATAPI packet command successfully\r
+                            and device sends data successfully.\r
+  @retval EFI_DEVICE_ERROR  the device failed to send data.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -542,35 +427,21 @@ AtapiPacketCommandIn (
   //\r
   return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);\r
 }\r
-\r
 /**\r
-  This function is used to send out ATAPI commands conforms to the \r
-  Packet Command with PIO Data Out Protocol.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *Packet\r
-  pointer pointing to ATAPI_PACKET_COMMAND data structure\r
-  which contains the contents of the command.\r
-\r
-  @param[in] *Buffer\r
-  buffer contained data transferred from host to device.\r
-\r
-  @param[in] ByteCount\r
-  data size in byte unit of the buffer.\r
-\r
-  @param[in] TimeOut\r
-  this parameter is used to specify the timeout \r
-  value for the PioReadWriteData() function. \r
-\r
-  @retval EFI_SUCCESS\r
-  send out the ATAPI packet command successfully\r
-  and device received data successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  the device failed to send data.\r
+  This function is used to send out ATAPI commands conforms to the Packet Command\r
+  with PIO Data Out Protocol.\r
+\r
+  @param IdeDev      pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                     to record all the information of the IDE device.\r
+  @param Packet      pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+                     which contains the contents of the command.\r
+  @param Buffer      buffer contained data transferred from host to device.\r
+  @param ByteCount   data size in byte unit of the buffer.\r
+  @param TimeOut     this parameter is used to specify the timeout value \r
+                     for the PioReadWriteData() function. \r
+  @retval EFI_SUCCESS      send out the ATAPI packet command successfully\r
+                           and device received data successfully.  \r
+  @retval EFI_DEVICE_ERROR the device failed to send data.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -655,213 +526,249 @@ AtapiPacketCommandOut (
   //\r
   return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);\r
 }\r
-\r
 /**\r
-  This function is called by either AtapiPacketCommandIn() or \r
-  AtapiPacketCommandOut(). It is used to transfer data between\r
-  host and device. The data direction is specified by the fourth\r
-  parameter.\r
+  Sends out ATAPI Inquiry Packet Command to the specified device. This command will\r
+  return INQUIRY data of the device.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                to record all the information of the IDE device.\r
 \r
-  @param[in] *Buffer\r
-  buffer contained data transferred between host and device.\r
+  @retval EFI_SUCCESS       Inquiry command completes successfully.\r
+  @retval EFI_DEVICE_ERROR  Inquiry command failed.\r
 \r
-  @param[in] ByteCount\r
-  data size in byte unit of the buffer.\r
+  @note  Parameter "IdeDev" will be updated in this function.\r
 \r
-  @param[in] Read\r
-  flag used to determine the data transfer direction.\r
-  Read equals 1, means data transferred from device to host;\r
-  Read equals 0, means data transferred from host to device.\r
+**/\r
+EFI_STATUS\r
+AtapiInquiry (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev\r
+  )\r
+{\r
+  ATAPI_PACKET_COMMAND  Packet;\r
+  EFI_STATUS            Status;\r
+  ATAPI_INQUIRY_DATA          *InquiryData;\r
+\r
+  //\r
+  // prepare command packet for the ATAPI Inquiry Packet Command.\r
+  //\r
+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+  Packet.Inquiry.opcode             = ATA_CMD_INQUIRY;\r
+  Packet.Inquiry.page_code          = 0;\r
+  Packet.Inquiry.allocation_length  = sizeof (ATAPI_INQUIRY_DATA);\r
+\r
+  InquiryData                       = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));\r
+  if (InquiryData == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Send command packet and get requested Inquiry data.\r
+  //\r
+  Status = AtapiPacketCommandIn (\r
+            IdeDev,\r
+            &Packet,\r
+            (UINT16 *) InquiryData,\r
+            sizeof (ATAPI_INQUIRY_DATA),\r
+            ATAPITIMEOUT\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (InquiryData);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  IdeDev->InquiryData = InquiryData;\r
 \r
-  @param[in] TimeOut\r
-  timeout value for wait DRQ ready before each data \r
-  stream's transfer.\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  This function is called by DiscoverIdeDevice() during its device\r
+  identification.\r
+  Its main purpose is to get enough information for the device media\r
+  to fill in the Media data structure of the Block I/O Protocol interface.\r
 \r
-  @retval EFI_SUCCESS\r
-  data is transferred successfully.\r
+  There are 5 steps to reach such objective:\r
+  1. Sends out the ATAPI Identify Command to the specified device. \r
+  Only ATAPI device responses to this command. If the command succeeds,\r
+  it returns the Identify data structure which filled with information \r
+  about the device. Since the ATAPI device contains removable media, \r
+  the only meaningful information is the device module name.\r
+  2. Sends out ATAPI Inquiry Packet Command to the specified device.\r
+  This command will return inquiry data of the device, which contains\r
+  the device type information.\r
+  3. Allocate sense data space for future use. We don't detect the media\r
+  presence here to improvement boot performance, especially when CD \r
+  media is present. The media detection will be performed just before\r
+  each BLK_IO read/write\r
   \r
-  @retval EFI_DEVICE_ERROR\r
-  the device failed to transfer data.\r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                 to record all the information of the IDE device.\r
 \r
+  @retval EFI_SUCCESS       Identify ATAPI device successfully.\r
+  @retval EFI_DEVICE_ERROR  ATAPI Identify Device Command failed or device type\r
+                            is not supported by this IDE driver.\r
+  @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed \r
+\r
+  @note   Parameter "IdeDev" will be updated in this function.\r
 **/\r
 EFI_STATUS\r
-PioReadWriteData (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT16          *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  BOOLEAN         Read,\r
-  IN  UINTN           TimeOut\r
+ATAPIIdentify (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev\r
   )\r
 {\r
+  EFI_IDENTIFY_DATA *AtapiIdentifyPointer;\r
+  UINT8             DeviceSelect;\r
+  EFI_STATUS        Status;\r
+\r
   //\r
-  // required transfer data in word unit.\r
+  // device select bit\r
   //\r
-  UINT32      RequiredWordCount;\r
+  DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);\r
 \r
+  AtapiIdentifyPointer  = AllocatePool (sizeof (EFI_IDENTIFY_DATA));\r
+  if (AtapiIdentifyPointer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
   //\r
-  // actual transfer data in word unit.\r
+  // Send ATAPI Identify Command to get IDENTIFY data.\r
   //\r
-  UINT32      ActualWordCount;\r
-  UINT32      WordCount;\r
-  EFI_STATUS  Status;\r
-  UINT16      *PtrBuffer;\r
+  Status = AtaPioDataIn (\r
+            IdeDev,\r
+            (VOID *) AtapiIdentifyPointer,\r
+            sizeof (EFI_IDENTIFY_DATA),\r
+            ATA_CMD_IDENTIFY_DEVICE,\r
+            DeviceSelect,\r
+            0,\r
+            0,\r
+            0,\r
+            0\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (AtapiIdentifyPointer);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  IdeDev->IdData = AtapiIdentifyPointer;\r
+  PrintAtaModuleName (IdeDev);\r
 \r
   //\r
-  // No data transfer is premitted.\r
+  // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
   //\r
-  if (ByteCount == 0) {\r
-    return EFI_SUCCESS;\r
+  Status = AtapiInquiry (IdeDev);\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (IdeDev->IdData);\r
+    //\r
+    // Make sure the pIdData will not be freed again.\r
+    //\r
+    IdeDev->IdData = NULL;\r
+    return EFI_DEVICE_ERROR;\r
   }\r
   //\r
-  // for performance, we assert the ByteCount is an even number\r
-  // which is actually a resonable assumption  \r
-  ASSERT((ByteCount%2) == 0);\r
-  \r
-  PtrBuffer         = Buffer;\r
-  RequiredWordCount = ByteCount / 2;\r
+  // Get media removable info from INQUIRY data.\r
   //\r
-  // ActuralWordCount means the word count of data really transferred.\r
+  IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80);\r
+\r
   //\r
-  ActualWordCount = 0;\r
+  // Identify device type via INQUIRY data.\r
+  //\r
+  switch (IdeDev->InquiryData->peripheral_type & 0x1f) {\r
+\r
+  //\r
+  // Magnetic Disk\r
+  //\r
+  case 0x00:\r
 \r
-  while (ActualWordCount < RequiredWordCount) {\r
-    \r
-    //\r
-    // before each data transfer stream, the host should poll DRQ bit ready,\r
-    // to see whether indicates device is ready to transfer data.\r
-    //\r
-    Status = DRQReady2 (IdeDev, TimeOut);\r
-    if (EFI_ERROR (Status)) {\r
-      return CheckErrorStatus (IdeDev);\r
-    }\r
-    \r
     //\r
-    // read Status Register will clear interrupt\r
+    // device is LS120 or ZIP drive.\r
     //\r
-    IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+    IdeDev->Type = IdeMagnetic;\r
 \r
+    IdeDev->BlkIo.Media->MediaId      = 0;\r
     //\r
-    // get current data transfer size from Cylinder Registers.\r
+    // Give initial value\r
     //\r
-    WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;\r
-    WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);\r
-    WordCount = WordCount & 0xffff;\r
-    WordCount /= 2;\r
+    IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
 \r
-    WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
+    IdeDev->BlkIo.Media->LastBlock  = 0;\r
+    IdeDev->BlkIo.Media->BlockSize  = 0x200;\r
+    break;\r
 \r
-    if (Read) {\r
-      IDEReadPortWMultiple (\r
-        IdeDev->PciIo,\r
-        IdeDev->IoPort->Data,\r
-        WordCount,\r
-        PtrBuffer\r
-        );\r
-    } else {\r
-      IDEWritePortWMultiple (\r
-        IdeDev->PciIo,\r
-        IdeDev->IoPort->Data,\r
-        WordCount,\r
-        PtrBuffer\r
-        );\r
-    }\r
+  //\r
+  // CD-ROM\r
+  //\r
+  case 0x05:\r
 \r
-    PtrBuffer += WordCount;\r
-    ActualWordCount += WordCount;\r
-  }\r
-  \r
-  if (Read) {\r
+    IdeDev->Type                      = IdeCdRom;\r
+    IdeDev->BlkIo.Media->MediaId      = 0;\r
     //\r
-    // In the case where the drive wants to send more data than we need to read,\r
-    // the DRQ bit will be set and cause delays from DRQClear2().\r
-    // We need to read data from the drive until it clears DRQ so we can move on.\r
+    // Give initial value\r
     //\r
-    AtapiReadPendingData (IdeDev);\r
-  }\r
+    IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
+\r
+    IdeDev->BlkIo.Media->LastBlock  = 0;\r
+    IdeDev->BlkIo.Media->BlockSize  = 0x800;\r
+    IdeDev->BlkIo.Media->ReadOnly   = TRUE;\r
+    break;\r
 \r
   //\r
-  // After data transfer is completed, normally, DRQ bit should clear.\r
+  // Tape\r
   //\r
-  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+  case 0x01:\r
 \r
   //\r
-  // read status register to check whether error happens.\r
+  // WORM\r
   //\r
-  return CheckErrorStatus (IdeDev);\r
-}\r
-\r
-/**\r
-  Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
-  to find out whether device is accessible.\r
-\r
-  @param[in] *IdeDev     Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-                         to record all the information of the IDE device.\r
-  @param[out] *SResult   Sense result for this packet command.\r
-\r
-  @retval EFI_SUCCESS      Device is accessible.\r
-  @retval EFI_DEVICE_ERROR Device is not accessible.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiTestUnitReady (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  OUT SENSE_RESULT    *SResult  \r
-  )\r
-{\r
-  ATAPI_PACKET_COMMAND  Packet;\r
-  EFI_STATUS            Status;\r
-  UINTN                                SenseCount;\r
-\r
+  case 0x04:\r
+  \r
   //\r
-  // fill command packet\r
+  // Optical\r
   //\r
-  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
-  Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
+  case 0x07:\r
+\r
+  default:\r
+    IdeDev->Type = IdeUnknown;\r
+    gBS->FreePool (IdeDev->IdData);\r
+    gBS->FreePool (IdeDev->InquiryData);\r
+    //\r
+    // Make sure the pIdData and pInquiryData will not be freed again.\r
+    //\r
+    IdeDev->IdData       = NULL;\r
+    IdeDev->InquiryData  = NULL;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   //\r
-  // send command packet\r
+  // original sense data numbers\r
   //\r
-  Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  IdeDev->SenseDataNumber = 20;\r
 \r
-  Status = AtapiRequestSense (IdeDev, &SenseCount);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+  IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));\r
+  if (IdeDev->SenseData == NULL) {\r
+    gBS->FreePool (IdeDev->IdData);\r
+    gBS->FreePool (IdeDev->InquiryData);\r
+    //\r
+    // Make sure the pIdData and pInquiryData will not be freed again.\r
+    //\r
+    IdeDev->IdData       = NULL;\r
+    IdeDev->InquiryData  = NULL;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  ParseSenseData (IdeDev, SenseCount, SResult);\r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
-  Sends out ATAPI Request Sense Packet Command to the specified device.\r
-  This command will return all the current Sense data in the device. \r
-  This function will pack all the Sense data in one single buffer.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[out] **SenseCounts\r
-  allocated in this function, and freed by the calling function.\r
-  This buffer is used to accommodate all the sense data returned \r
-  by the device.\r
-\r
-  @retval EFI_SUCCESS\r
-  Request Sense command completes successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Request Sense command failed.\r
-\r
+  Sends out ATAPI Request Sense Packet Command to the specified device. This command\r
+  will return all the current Sense data in the device.  This function will pack \r
+  all the Sense data in one single buffer.\r
+\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param SenseCounts  allocated in this function, and freed by the calling function.\r
+                      This buffer is used to accommodate all the sense data returned \r
+                      by the device.\r
+\r
+  @retval EFI_SUCCESS      Request Sense command completes successfully.\r
+  @retval EFI_DEVICE_ERROR Request Sense command failed.\r
 **/\r
 EFI_STATUS\r
 AtapiRequestSense (\r
@@ -918,30 +825,148 @@ AtapiRequestSense (
       }\r
     }\r
 \r
-    (*SenseCounts)++;\r
-    //\r
-    // We limit MAX sense data count to 20 in order to avoid dead loop. Some\r
-    // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.\r
-    // In this case, dead loop occurs if we don't have a gatekeeper. 20 is\r
-    // supposed to be large enough for any ATAPI device.\r
-    //\r
-    if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {\r
-      //\r
-      // Ptr is word-based pointer\r
-      //\r
-      Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;\r
+    (*SenseCounts)++;\r
+    //\r
+    // We limit MAX sense data count to 20 in order to avoid dead loop. Some\r
+    // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.\r
+    // In this case, dead loop occurs if we don't have a gatekeeper. 20 is\r
+    // supposed to be large enough for any ATAPI device.\r
+    //\r
+    if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {\r
+      //\r
+      // Ptr is word-based pointer\r
+      //\r
+      Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;\r
+\r
+    } else {\r
+      //\r
+      // when no sense key, skip out the loop\r
+      //\r
+      FetchSenseData = FALSE;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  This function is used to parse sense data. Only the first sense data is honoured\r
+  \r
+  @param IdeDev     Indicates the calling context.\r
+  @param SenseCount Count of sense data.\r
+  @param Result    The parsed result.\r
+\r
+  @retval EFI_SUCCESS           Successfully parsed.\r
+  @retval EFI_INVALID_PARAMETER Count of sense data is zero.\r
+\r
+**/\r
+EFI_STATUS\r
+ParseSenseData (\r
+  IN IDE_BLK_IO_DEV     *IdeDev,\r
+  IN UINTN              SenseCount,\r
+  OUT SENSE_RESULT      *Result\r
+  )\r
+{\r
+  ATAPI_REQUEST_SENSE_DATA      *SenseData;\r
+\r
+  if (SenseCount == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Only use the first sense data\r
+  //\r
+  SenseData = IdeDev->SenseData;\r
+  *Result   = SenseOtherSense;\r
+\r
+  switch (SenseData->sense_key) {\r
+  case ATA_SK_NO_SENSE:\r
+    *Result = SenseNoSenseKey;\r
+    break;\r
+  case ATA_SK_NOT_READY:\r
+    switch (SenseData->addnl_sense_code) {\r
+    case ATA_ASC_NO_MEDIA:\r
+      *Result = SenseNoMedia;\r
+      break;\r
+    case ATA_ASC_MEDIA_UPSIDE_DOWN:\r
+      *Result = SenseMediaError;\r
+      break;\r
+    case ATA_ASC_NOT_READY:\r
+      if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {\r
+        *Result = SenseDeviceNotReadyNeedRetry;\r
+      } else {\r
+        *Result = SenseDeviceNotReadyNoRetry;\r
+      }\r
+      break;\r
+    }\r
+    break;\r
+  case ATA_SK_UNIT_ATTENTION:\r
+    if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {\r
+      *Result = SenseMediaChange;\r
+    }\r
+    break;\r
+  case ATA_SK_MEDIUM_ERROR:\r
+    switch (SenseData->addnl_sense_code) {\r
+    case ATA_ASC_MEDIA_ERR1:\r
+    case ATA_ASC_MEDIA_ERR2:\r
+    case ATA_ASC_MEDIA_ERR3:\r
+    case ATA_ASC_MEDIA_ERR4:\r
+      *Result = SenseMediaError;\r
+      break;\r
+    }\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
+  to find out whether device is accessible.\r
+\r
+  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param SResult   Sense result for this packet command.\r
+\r
+  @retval EFI_SUCCESS      Device is accessible.\r
+  @retval EFI_DEVICE_ERROR Device is not accessible.\r
+\r
+**/\r
+EFI_STATUS\r
+AtapiTestUnitReady (\r
+  IN  IDE_BLK_IO_DEV  *IdeDev,\r
+  OUT SENSE_RESULT    *SResult  \r
+  )\r
+{\r
+  ATAPI_PACKET_COMMAND  Packet;\r
+  EFI_STATUS            Status;\r
+  UINTN                                SenseCount;\r
+\r
+  //\r
+  // fill command packet\r
+  //\r
+  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
+  Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
+\r
+  //\r
+  // send command packet\r
+  //\r
+  Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-    } else {\r
-      //\r
-      // when no sense key, skip out the loop\r
-      //\r
-      FetchSenseData = FALSE;\r
-    }\r
+  Status = AtapiRequestSense (IdeDev, &SenseCount);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
 \r
+  ParseSenseData (IdeDev, SenseCount, SResult);\r
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
 /**\r
   Sends out ATAPI Read Capacity Packet Command to the specified device.\r
   This command will return the information regarding the capacity of the\r
@@ -953,16 +978,17 @@ AtapiRequestSense (
   if the Read Capacity Command failed, the Sense data must be requested\r
   and be analyzed to determine if the Read Capacity Command should retry.\r
 \r
-  @param[in] *IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-                        to record all the information of the IDE device.\r
-  @param[out] SResult   Sense result for this packet command\r
+  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param SResult   Sense result for this packet command\r
 \r
   @retval EFI_SUCCESS      Read Capacity Command finally completes successfully.\r
   @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.\r
+  @retval EFI_NOT_READY    Operation succeeds but returned capacity is 0\r
 \r
   @note Parameter "IdeDev" will be updated in this function.\r
 \r
-  TODO:    EFI_NOT_READY - add return value to function comment\r
+  \r
 **/\r
 EFI_STATUS\r
 AtapiReadCapacity (\r
@@ -1082,30 +1108,70 @@ AtapiReadCapacity (
     return EFI_DEVICE_ERROR;\r
   }\r
 }\r
+/**\r
+  This function is used to test the current media write-protected or not residing\r
+  in the LS-120 drive or ZIP drive. \r
+  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                         to record all the information of the IDE device.\r
+  @param WriteProtected  if True, current media is write protected.\r
+                         if FALSE, current media is writable\r
+\r
+  @retval EFI_SUCCESS         The media write-protected status is achieved successfully\r
+  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.\r
+**/\r
+EFI_STATUS\r
+IsLS120orZipWriteProtected (\r
+  IN  IDE_BLK_IO_DEV    *IdeDev,\r
+  OUT BOOLEAN           *WriteProtected\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  *WriteProtected = FALSE;\r
+\r
+  Status          = LS120EnableMediaStatus (IdeDev, TRUE);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // the Get Media Status Command is only valid\r
+  // if a Set Features/Enable Media Status Command has been priviously issued.\r
+  //\r
+  if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {\r
+\r
+    *WriteProtected = TRUE;\r
+  } else {\r
+\r
+    *WriteProtected = FALSE;\r
+  }\r
+\r
+  //\r
+  // After Get Media Status Command completes,\r
+  // Set Features/Disable Media Command should be sent.\r
+  //\r
+  Status = LS120EnableMediaStatus (IdeDev, FALSE);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
-  Used before read/write blocks from/to ATAPI device media. \r
-  Since ATAPI device media is removable, it is necessary to detect\r
-  whether media is present and get current present media's\r
-  information, and if media has been changed, Block I/O Protocol\r
-  need to be reinstalled.\r
-\r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[out] *MediaChange\r
-  return value that indicates if the media of the device has been\r
-  changed.\r
-\r
-  @retval EFI_SUCCESS\r
-  media found successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  any error encounters during media detection.\r
-  \r
-  @retval EFI_NO_MEDIA\r
-  media not found.\r
+  Used before read/write blocks from/to ATAPI device media. Since ATAPI device \r
+  media is removable, it is necessary to detect whether media is present and \r
+  get current present media's information, and if media has been changed, Block\r
+  I/O Protocol need to be reinstalled.\r
+\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param MediaChange  return value that indicates if the media of the device has been\r
+                      changed.\r
+\r
+  @retval EFI_SUCCESS       media found successfully.\r
+  @retval EFI_DEVICE_ERROR  any error encounters during media detection.\r
+  @retval EFI_NO_MEDIA      media not found.\r
 \r
   @note\r
   parameter IdeDev may be updated in this function.\r
@@ -1350,22 +1416,14 @@ AtapiDetectMedia (
   65536. This is the main difference between READ(10) and READ(12) \r
   Command. The maximum number of blocks in READ(12) is 2 power 32.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *Buffer\r
-  A pointer to the destination buffer for the data. \r
-\r
-  @param[in] Lba\r
-  The starting logical block address to read from \r
-  on the device media.\r
+  @param IdeDev           pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                          to record all the information of the IDE device.\r
+  @param Buffer           A pointer to the destination buffer for the data. \r
+  @param Lba              The starting logical block address to read from on the \r
+                          device media.\r
+  @param NumberOfBlocks   The number of transfer data blocks.\r
 \r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
-\r
-  @return status is fully dependent on the return status\r
-  of AtapiPacketCommandIn() function.\r
+  @return status is fully dependent on the return status of AtapiPacketCommandIn() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1475,22 +1533,14 @@ AtapiReadSectors (
   unit. The maximum number of blocks that can be transferred once is\r
   65536. \r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *Buffer\r
-  A pointer to the source buffer for the data. \r
-\r
-  @param[in] Lba\r
-  The starting logical block address to write onto \r
-  the device media.\r
-\r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
-\r
-  @return status is fully dependent on the return status\r
-  of AtapiPacketCommandOut() function.\r
+  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                         to record all the information of the IDE device.\r
+  @param Buffer          A pointer to the source buffer for the data. \r
+  @param Lba             The starting logical block address to write onto \r
+                         the device media.\r
+  @param NumberOfBlocks  The number of transfer data blocks.\r
+  \r
+  @return status is fully dependent on the return status of AtapiPacketCommandOut() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1586,7 +1636,6 @@ AtapiWriteSectors (
 \r
   return Status;\r
 }\r
-\r
 /**\r
   This function is used to implement the Soft Reset on the specified\r
   ATAPI device. Different from the AtaSoftReset(), here reset is a ATA\r
@@ -1599,15 +1648,11 @@ AtapiWriteSectors (
   This function is called by IdeBlkIoReset(), \r
   a interface function of Block I/O protocol.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
 \r
-  @retval EFI_SUCCESS\r
-  Soft reset completes successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Any step during the reset process is failed.\r
+  @retval EFI_SUCCESS      Soft reset completes successfully.\r
+  @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1651,45 +1696,23 @@ AtapiSoftReset (
   This function is the ATAPI implementation for ReadBlocks in the\r
   Block I/O Protocol interface.\r
 \r
-  @param[in] *IdeBlkIoDevice\r
-  Indicates the calling context.\r
-\r
-  @param[in] MediaId\r
-  The media id that the read request is for.\r
-\r
-  @param[in] LBA\r
-  The starting logical block address to read from \r
-  on the device.\r
-\r
-  @param[in] BufferSize\r
-  The size of the Buffer in bytes. This must be a\r
-  multiple of the intrinsic block size of the device.\r
-\r
-  @param[out] *Buffer\r
-  A pointer to the destination buffer for the data. \r
-  The caller is responsible for either having implicit\r
-  or explicit ownership of the memory that data is read into.\r
-\r
-  @retval EFI_SUCCESS\r
-  Read Blocks successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Read Blocks failed.\r
-  \r
-  @retval EFI_NO_MEDIA\r
-  There is no media in the device.\r
+  @param IdeBlkIoDevice Indicates the calling context.\r
+  @param MediaId        The media id that the read request is for.\r
+  @param LBA            The starting logical block address to read from on the device.\r
+  @param BufferSize     The size of the Buffer in bytes. This must be a multiple\r
+                        of the intrinsic block size of the device.\r
+  @param Buffer         A pointer to the destination buffer for the data. The caller\r
+                        is responsible for either having implicit or explicit \r
+                        ownership of the memory that data is read into.\r
   \r
-  @retval EFI_MEDIA_CHANGED\r
-  The MediaId is not for the current media.\r
-  \r
-  @retval EFI_BAD_BUFFER_SIZE\r
-  The BufferSize parameter is not a multiple of the\r
-  intrinsic block size of the device.\r
-  \r
-  @retval EFI_INVALID_PARAMETER\r
-  The read request contains LBAs that are not valid,\r
-  or the data buffer is not valid.\r
-\r
+  @retval EFI_SUCCESS           Read Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR      Read Blocks failed.\r
+  @retval EFI_NO_MEDIA          There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
+                                or the data buffer is not valid.\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoReadBlocks (\r
@@ -1799,53 +1822,29 @@ AtapiBlkIoReadBlocks (
   return EFI_SUCCESS;\r
 \r
 }\r
-\r
 /**\r
   This function is the ATAPI implementation for WriteBlocks in the\r
   Block I/O Protocol interface.\r
 \r
-  @param[in] *IdeBlkIoDevice\r
-  Indicates the calling context.\r
-\r
-  @param[in] MediaId\r
-  The media id that the write request is for.\r
-\r
-  @param[in] LBA\r
-  The starting logical block address to write onto \r
-  the device.\r
-\r
-  @param[in] BufferSize\r
-  The size of the Buffer in bytes. This must be a\r
-  multiple of the intrinsic block size of the device.\r
-\r
-  @param[out] *Buffer\r
-  A pointer to the source buffer for the data. \r
-  The caller is responsible for either having implicit\r
-  or explicit ownership of the memory that data is \r
-  written from.\r
-\r
-  @retval EFI_SUCCESS\r
-  Write Blocks successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Write Blocks failed.\r
-  \r
-  @retval EFI_NO_MEDIA\r
-  There is no media in the device.\r
-  \r
-  @retval EFI_MEDIA_CHANGE\r
-  The MediaId is not for the current media.\r
-  \r
-  @retval EFI_BAD_BUFFER_SIZE\r
-  The BufferSize parameter is not a multiple of the\r
-  intrinsic block size of the device.\r
-  \r
-  @retval EFI_INVALID_PARAMETER\r
-  The write request contains LBAs that are not valid,\r
-  or the data buffer is not valid.\r
-\r
-  TODO:    EFI_MEDIA_CHANGED - add return value to function comment\r
-  TODO:    EFI_WRITE_PROTECTED - add return value to function comment\r
+  @param IdeBlkIoDevice  Indicates the calling context.\r
+  @param MediaId         The media id that the write request is for.\r
+  @param LBA             The starting logical block address to write onto the device.\r
+  @param BufferSize      The size of the Buffer in bytes. This must be a multiple\r
+                         of the intrinsic block size of the device.\r
+  @param Buffer          A pointer to the source buffer for the data. The caller\r
+                         is responsible for either having implicit or explicit ownership\r
+                         of the memory that data is written from.\r
+\r
+  @retval EFI_SUCCESS            Write Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR       Write Blocks failed.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE       The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the\r
+                                 intrinsic block size of the device.  \r
+  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid, \r
+                                 or the data buffer is not valid.\r
+\r
+  @retval EFI_WRITE_PROTECTED    The write protected is enabled or the media does not support write\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoWriteBlocks (\r
@@ -1949,162 +1948,5 @@ AtapiBlkIoWriteBlocks (
 \r
 }\r
 \r
-/**\r
-  This function is used to parse sense data. Only the first\r
-  sense data is honoured.\r
-\r
-  @param[in] IdeDev     Indicates the calling context.\r
-  @param[in] SenseCount Count of sense data.\r
-  @param[out] Result    The parsed result.\r
-\r
-  @retval EFI_SUCCESS           Successfully parsed.\r
-  @retval EFI_INVALID_PARAMETER Count of sense data is zero.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSenseData (\r
-  IN IDE_BLK_IO_DEV     *IdeDev,\r
-  IN UINTN              SenseCount,\r
-  OUT SENSE_RESULT      *Result\r
-  )\r
-{\r
-  ATAPI_REQUEST_SENSE_DATA      *SenseData;\r
-\r
-  if (SenseCount == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Only use the first sense data\r
-  //\r
-  SenseData = IdeDev->SenseData;\r
-  *Result   = SenseOtherSense;\r
-\r
-  switch (SenseData->sense_key) {\r
-  case ATA_SK_NO_SENSE:\r
-    *Result = SenseNoSenseKey;\r
-    break;\r
-  case ATA_SK_NOT_READY:\r
-    switch (SenseData->addnl_sense_code) {\r
-    case ATA_ASC_NO_MEDIA:\r
-      *Result = SenseNoMedia;\r
-      break;\r
-    case ATA_ASC_MEDIA_UPSIDE_DOWN:\r
-      *Result = SenseMediaError;\r
-      break;\r
-    case ATA_ASC_NOT_READY:\r
-      if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {\r
-        *Result = SenseDeviceNotReadyNeedRetry;\r
-      } else {\r
-        *Result = SenseDeviceNotReadyNoRetry;\r
-      }\r
-      break;\r
-    }\r
-    break;\r
-  case ATA_SK_UNIT_ATTENTION:\r
-    if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {\r
-      *Result = SenseMediaChange;\r
-    }\r
-    break;\r
-  case ATA_SK_MEDIUM_ERROR:\r
-    switch (SenseData->addnl_sense_code) {\r
-    case ATA_ASC_MEDIA_ERR1:\r
-    case ATA_ASC_MEDIA_ERR2:\r
-    case ATA_ASC_MEDIA_ERR3:\r
-    case ATA_ASC_MEDIA_ERR4:\r
-      *Result = SenseMediaError;\r
-      break;\r
-    }\r
-    break;\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function reads the pending data in the device.\r
-\r
-  @param[in] IdeDev   Indicates the calling context.\r
-\r
-  @retval EFI_SUCCESS   Successfully read.\r
-  @retval EFI_NOT_READY The BSY is set avoiding reading.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadPendingData (\r
-  IN IDE_BLK_IO_DEV     *IdeDev\r
-  )\r
-{\r
-  UINT8     AltRegister;\r
-  UINT16    TempWordBuffer;\r
-\r
-  AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);\r
-  if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {\r
-    return EFI_NOT_READY;\r
-  }\r
-  if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
-    TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
-    while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
-      IDEReadPortWMultiple (\r
-        IdeDev->PciIo,\r
-        IdeDev->IoPort->Data, \r
-        1, \r
-        &TempWordBuffer\r
-        );\r
-      TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);\r
-    }\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  WriteProtected TODO: add argument description\r
-\r
-  @retval  EFI_DEVICE_ERROR TODO: Add description for return value\r
-  @retval  EFI_DEVICE_ERROR TODO: Add description for return value\r
-  @retval  EFI_SUCCESS TODO: Add description for return value.\r
-\r
-**/\r
-EFI_STATUS\r
-IsLS120orZipWriteProtected (\r
-  IN  IDE_BLK_IO_DEV    *IdeDev,\r
-  OUT BOOLEAN           *WriteProtected\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  *WriteProtected = FALSE;\r
-\r
-  Status          = LS120EnableMediaStatus (IdeDev, TRUE);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // the Get Media Status Command is only valid\r
-  // if a Set Features/Enable Media Status Command has been priviously issued.\r
-  //\r
-  if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {\r
-\r
-    *WriteProtected = TRUE;\r
-  } else {\r
-\r
-    *WriteProtected = FALSE;\r
-  }\r
 \r
-  //\r
-  // After Get Media Status Command completes,\r
-  // Set Features/Disable Media Command should be sent.\r
-  //\r
-  Status = LS120EnableMediaStatus (IdeDev, FALSE);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
 \r
-  return EFI_SUCCESS;\r
-}\r
index 9a4f92fb0a16188cf4168aa54d6ab8d5a2545c39..b021f3554478e677149dee5f19ff5cec850c3263 100644 (file)
@@ -1,4 +1,6 @@
 /** @file\r
+  UEFI Component Name(2) protocol implementation for ConPlatform driver.\r
+  \r
   Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
   All rights reserved. This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
index b75fd3f8d4d5258769dc2a12d705899d78fdf87f..6d6d001e5fa3e336833f9ab31ac6b3d2885ae0ca 100644 (file)
@@ -1,4 +1,7 @@
 /** @file\r
+  \r
+  UEFI Component Name(2) protocol implementation header file for IDE Bus driver.\r
+  \r
   Copyright (c) 2006, Intel Corporation\r
   All rights reserved. This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -13,7 +16,7 @@
 #ifndef _IDE_BUS_COMPONENT_NAME_H_\r
 #define _IDE_BUS_COMPONENT_NAME_H_\r
 \r
-#define ADD_NAME(x) AddName ((x));\r
+#define ADD_IDE_ATAPI_NAME(x) AddName ((x));\r
 \r
 extern EFI_COMPONENT_NAME_PROTOCOL   gIDEBusComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL  gIDEBusComponentName2;\r
@@ -150,11 +153,9 @@ IDEBusComponentNameGetControllerName (
 \r
 \r
 /**\r
-  TODO: Add function description\r
+  Add the component name for the IDE/ATAPI device\r
 \r
-  @param  IdeBlkIoDevicePtr TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param  IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance.\r
 \r
 **/\r
 VOID\r
index 97e51b2b0be562d3f12cf3796c2d3101e442c761..8beb95608e8512756b84e3d076684b792149c2cb 100644 (file)
@@ -1,4 +1,7 @@
 /** @file\r
+  Implementation of UEFI Driver Configuration Protocol for IDE bus driver which \r
+  provides ability to set IDE bus controller specific options.\r
+  \r
   Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
   All rights reserved. This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
@@ -31,11 +34,11 @@ EFI_DRIVER_CONFIGURATION_PROTOCOL gIDEBusDriverConfiguration = {
 };\r
 \r
 /**\r
-  TODO: Add function description\r
+  Interprete keyboard input.\r
 \r
-  @retval  EFI_ABORTED TODO: Add description for return value.\r
-  @retval  EFI_SUCCESS TODO: Add description for return value.\r
-  @retval  EFI_NOT_FOUND TODO: Add description for return value.\r
+  @retval  EFI_ABORTED  Get an 'ESC' key inputed.\r
+  @retval  EFI_SUCCESS  Get an 'Y' or 'y' inputed.\r
+  @retval  EFI_NOT_FOUND Get an 'N' or 'n' inputed..\r
 \r
 **/\r
 EFI_STATUS\r
@@ -80,46 +83,35 @@ GetResponse (
   Allows the user to set controller specific options for a controller that a \r
   driver is currently managing.\r
 \r
-  @param  This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
-  instance.\r
-  @param  ControllerHandle The handle of the controller to set options on.\r
-  @param  ChildHandle The handle of the child controller to set options on.\r
-  This is an optional parameter that may be NULL.\r
-  It will be NULL for device drivers, and for a bus drivers\r
-  that wish to set options for the bus controller.\r
-  It will not be NULL for a bus driver that wishes to set\r
-  options for one of its child controllers.\r
-  @param  Language A pointer to a three character ISO 639-2 language\r
-  identifier. This is the language of the user interface\r
-  that should be presented to the user, and it must match\r
-  one of the languages specified in SupportedLanguages.\r
-  The number of languages supported by a driver is up to\r
-  the driver writer.\r
-  @param  ActionRequired A pointer to the action that the calling agent is\r
-  required to perform when this function returns.\r
-  See "Related Definitions" for a list of the actions that\r
-  the calling agent is required to perform prior to\r
-  accessing ControllerHandle again.\r
-\r
-  @retval  EFI_SUCCESS The driver specified by This successfully set the\r
-  configuration options for the controller specified\r
-  by ControllerHandle..\r
+  @param  This              A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+  @param  ControllerHandle  The handle of the controller to set options on.\r
+  @param  ChildHandle       The handle of the child controller to set options on.\r
+                            This is an optional parameter that may be NULL.\r
+                            It will be NULL for device drivers, and for a bus drivers\r
+                            that wish to set options for the bus controller.\r
+                            It will not be NULL for a bus driver that wishes to set\r
+                            options for one of its child controllers.\r
+  @param  Language          A pointer to a three character ISO 639-2 language identifier. \r
+                            This is the language of the user interface that should be presented \r
+                            to the user, and it must match one of the languages specified in \r
+                            SupportedLanguages. The number of languages supported by a driver is up to\r
+                            the driver writer.\r
+  @param  ActionRequired    A pointer to the action that the calling agent is required \r
+                            to perform when this function returns.\r
+  \r
+\r
+  @retval  EFI_SUCCESS           The driver specified by This successfully set the configuration \r
+                                 options for the controller specified by ControllerHandle..\r
   @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
-  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
-  valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
   @retval  EFI_INVALID_PARAMETER ActionRequired is NULL.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support\r
-  setting configuration options for the controller\r
-  specified by ControllerHandle and ChildHandle.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support the\r
-  language specified by Language.\r
-  @retval  EFI_DEVICE_ERROR A device error occurred while attempt to set the\r
-  configuration options for the controller specified\r
-  by ControllerHandle and ChildHandle.\r
-  @retval  EFI_OUT_RESOURCES There are not enough resources available to set the\r
-  configuration options for the controller specified\r
-  by ControllerHandle and ChildHandle.\r
-\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support setting configuration options for \r
+                                 the controller specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the language specified by Language.\r
+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempt to set the configuration options for the \r
+                                 controller specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_OUT_RESOURCES     There are not enough resources available to set the configuration options for the \r
+                                 controller specified by ControllerHandle and ChildHandle\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -189,35 +181,25 @@ IDEBusDriverConfigurationSetOptions (
 /**\r
   Tests to see if a controller's current configuration options are valid.\r
 \r
-  @param  This A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL\r
-  instance.\r
-  @param  ControllerHandle The handle of the controller to test if it's current\r
-  configuration options are valid.\r
-  @param  ChildHandle The handle of the child controller to test if it's\r
-  current\r
-  configuration options are valid.  This is an optional\r
-  parameter that may be NULL.  It will be NULL for device\r
-  drivers.  It will also be NULL for a bus drivers that\r
-  wish to test the configuration options for the bus\r
-  controller. It will not be NULL for a bus driver that\r
-  wishes to test configuration options for one of\r
-  its child controllers.\r
-\r
-  @retval  EFI_SUCCESS The controller specified by ControllerHandle and\r
-  ChildHandle that is being managed by the driver\r
-  specified by This has a valid set of  configuration\r
-  options.\r
+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.\r
+  @param  ControllerHandle The handle of the controller to test if it's current configuration options \r
+                           are valid.\r
+  @param  ChildHandle      The handle of the child controller to test if it's current configuration \r
+                           options are valid.  This is an optional parameter that may be NULL. It will \r
+                           be NULL for device drivers.  It will also be NULL for a bus drivers that\r
+                           wish to test the configuration options for the bus controller. It will \r
+                           not be NULL for a bus driver that wishes to test configuration options for \r
+                           one of its child controllers.\r
+  @retval  EFI_SUCCESS           The controller specified by ControllerHandle and ChildHandle that is being\r
+                                 managed by the driver specified by This has a valid set of  configuration\r
+                                 options.\r
   @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
-  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
-  EFI_HANDLE.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This is not currently\r
-  managing the controller specified by\r
-  ControllerHandle and ChildHandle.\r
-  @retval  EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
-  ChildHandle that is being managed by the driver\r
-  specified by This has an invalid set of\r
-  configuration options.\r
-\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This is not currently  managing the controller \r
+                                 specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_DEVICE_ERROR      The controller specified by ControllerHandle and ChildHandle that is being\r
+                                 managed by the driver specified by This has an invalid set of configuration\r
+                                 options.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -249,51 +231,37 @@ IDEBusDriverConfigurationOptionsValid (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
   Forces a driver to set the default configuration options for a controller.\r
 \r
-  @param  This A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL\r
-  instance.\r
-  @param  ControllerHandle The handle of the controller to force default\r
-  configuration options on.\r
-  @param  ChildHandle The handle of the child controller to force default\r
-  configuration options on  This is an optional parameter\r
-  that may be NULL.  It will be NULL for device drivers.\r
-  It will also be NULL for a bus drivers that wish to\r
-  force default configuration options for the bus\r
-  controller.  It will not be NULL for a bus driver that\r
-  wishes to force default configuration options for one\r
-  of its child controllers.\r
-  @param  DefaultType The type of default configuration options to force on\r
-  the controller specified by ControllerHandle and\r
-  ChildHandle.  See Table 9-1 for legal values.\r
-  A DefaultType of 0x00000000 must be supported\r
-  by this protocol.\r
-  @param  ActionRequired A pointer to the action that the calling agent\r
-  is required to perform when this function returns.\r
-\r
-  @retval  EFI_SUCCESS The driver specified by This successfully forced\r
-  the default configuration options on the\r
-  controller specified by ControllerHandle and\r
-  ChildHandle.\r
+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+  @param  ControllerHandle The handle of the controller to force default configuration options on.\r
+  @param  ChildHandle      The handle of the child controller to force default configuration \r
+                           options on  This is an optional parameter that may be NULL.  It \r
+                           will be NULL for device drivers. It will also be NULL for a bus \r
+                           drivers that wish to force default configuration options for the bus\r
+                           controller.  It will not be NULL for a bus driver that wishes to force\r
+                           default configuration options for one of its child controllers.\r
+  @param  DefaultType      The type of default configuration options to force on the controller \r
+                           specified by ControllerHandle and ChildHandle. \r
+  @param  ActionRequired   A pointer to the action that the calling agent is required to perform \r
+                           when this function returns.\r
+\r
+  @retval  EFI_SUCCESS           The driver specified by This successfully forced the \r
+                                 default configuration options on the controller specified by \r
+                                 ControllerHandle and ChildHandle.\r
   @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
-  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a\r
-  valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
   @retval  EFI_INVALID_PARAMETER ActionRequired is NULL.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support\r
-  forcing the default configuration options on\r
-  the controller specified by ControllerHandle\r
-  and ChildHandle.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support\r
-  the configuration type specified by DefaultType.\r
-  @retval  EFI_DEVICE_ERROR A device error occurred while attempt to force\r
-  the default configuration options on the controller\r
-  specified by  ControllerHandle and ChildHandle.\r
-  @retval  EFI_OUT_RESOURCES There are not enough resources available to force\r
-  the default configuration options on the controller\r
-  specified by ControllerHandle and ChildHandle.\r
-\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support forcing the default \r
+                                 configuration options on the controller specified by ControllerHandle\r
+                                 and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the configuration type \r
+                                 specified by DefaultType.\r
+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempt to force the default configuration \r
+                                 options on the controller specified by  ControllerHandle and ChildHandle.\r
+  @retval  EFI_OUT_RESOURCES     There are not enough resources available to force the default configuration \r
+                                 options on the controller specified by ControllerHandle and ChildHandle.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
index 85d2bf3ad8720cc125b3cd22da0ed75a7d4fb369..5e1383c0c265b9cf4d09fd72ce3f6352ea570a8a 100644 (file)
@@ -1,4 +1,7 @@
 /** @file\r
+  Implementation of UEFI driver Dialnostics protocol which to perform diagnostic on the IDE\r
+  Bus controller.\r
+  \r
   Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
   All rights reserved. This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
@@ -34,59 +37,49 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gIDEBusDriverDiag
 /**\r
   Runs diagnostics on a controller.\r
 \r
-  @param  This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL\r
-  instance.\r
+  @param  This             A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOLinstance.\r
   @param  ControllerHandle The handle of the controller to run diagnostics on.\r
-  @param  ChildHandle The handle of the child controller to run diagnostics on\r
-  This is an optional parameter that may be NULL.  It will\r
-  be NULL for device drivers.  It will also be NULL for a\r
-  bus drivers that wish to run diagnostics on the bus\r
-  controller.  It will not be NULL for a bus driver that\r
-  wishes to run diagnostics on one of its child\r
-  controllers.\r
-  @param  DiagnosticType Indicates type of diagnostics to perform on the\r
-  controller specified by ControllerHandle and ChildHandle.\r
-  See "Related Definitions" for the list of supported\r
-  types.\r
-  @param  Language A pointer to a three character ISO 639-2 language\r
-  identifier.  This is the language in which the optional\r
-  error message should be returned in Buffer, and it must\r
-  match one of the languages specified in\r
-  SupportedLanguages. The number of languages supported by\r
-  a driver is up to the driver writer.\r
-  @param  ErrorType A GUID that defines the format of the data returned in\r
-  Buffer.\r
-  @param  BufferSize The size, in bytes, of the data returned in Buffer.\r
-  @param  Buffer A buffer that contains a Null-terminated Unicode string\r
-  plus some additional data whose format is defined by\r
-  ErrorType.  Buffer is allocated by this function with\r
-  AllocatePool(), and it is the caller's responsibility\r
-  to free it with a call to FreePool().\r
-\r
-  @retval  EFI_SUCCESS The controller specified by ControllerHandle and\r
-  ChildHandle passed the diagnostic.\r
+  @param  ChildHandle      The handle of the child controller to run diagnostics on\r
+                           This is an optional parameter that may be NULL.  It will\r
+                           be NULL for device drivers.  It will also be NULL for a\r
+                           bus drivers that wish to run diagnostics on the bus controller. \r
+                           It will not be NULL for a bus driver that wishes to run \r
+                           diagnostics on one of its child controllers.\r
+  @param  DiagnosticType   Indicates type of diagnostics to perform on the controller\r
+                           specified by ControllerHandle and ChildHandle.\r
+  @param  Language         A pointer to a three character ISO 639-2 language identifier. \r
+                           This is the language in which the optional error message should \r
+                           be returned in Buffer, and it must match one of the languages \r
+                           specified in SupportedLanguages. The number of languages supported by\r
+                           a driver is up to the driver writer.\r
+  @param  ErrorType        A GUID that defines the format of the data returned in Buffer.\r
+  @param  BufferSize       The size, in bytes, of the data returned in Buffer.\r
+  @param  Buffer           A buffer that contains a Null-terminated Unicode string\r
+                           plus some additional data whose format is defined by ErrorType.  \r
+                           Buffer is allocated by this function with AllocatePool(), and \r
+                           it is the caller's responsibility to free it with a call to FreePool().\r
+\r
+  @retval  EFI_SUCCESS           The controller specified by ControllerHandle and ChildHandle passed \r
+                                 the diagnostic.\r
   @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
-  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
-  EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
   @retval  EFI_INVALID_PARAMETER Language is NULL.\r
   @retval  EFI_INVALID_PARAMETER ErrorType is NULL.\r
   @retval  EFI_INVALID_PARAMETER BufferType is NULL.\r
   @retval  EFI_INVALID_PARAMETER Buffer is NULL.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support\r
-  running diagnostics for the controller specified\r
-  by ControllerHandle and ChildHandle.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support the\r
-  type of diagnostic specified by DiagnosticType.\r
-  @retval  EFI_UNSUPPORTED The driver specified by This does not support the\r
-  language specified by Language.\r
-  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to complete\r
-  the diagnostics.\r
-  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to return\r
-  the status information in ErrorType, BufferSize,\r
-  and Buffer.\r
-  @retval  EFI_DEVICE_ERROR The controller specified by ControllerHandle and\r
-  ChildHandle did not pass the diagnostic.\r
-\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support running \r
+                                 diagnostics for the controller specified by ControllerHandle \r
+                                 and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the\r
+                                 type of diagnostic specified by DiagnosticType.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the language \r
+                                 specified by Language.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to complete the \r
+                                 diagnostics.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to return the \r
+                                 status information in ErrorType, BufferSize,and Buffer.\r
+  @retval  EFI_DEVICE_ERROR      The controller specified by ControllerHandle and ChildHandle \r
+                                 did not pass the diagnostic.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
index 96f1ce3bd8fe2c51a377cdf9f60d6968d1aebb54..fa4d636acb60dfef5128db97eec252b810ecdff8 100644 (file)
@@ -1,4 +1,6 @@
 /** @file\r
+  The file ontaining the helper functions implement of the Ide Bus driver\r
+  \r
   Copyright (c) 2006 - 2008, Intel Corporation\r
   All rights reserved. This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -19,13 +21,12 @@ BOOLEAN MasterDeviceExist     = FALSE;
 UINT8   MasterDeviceType      = INVALID_DEVICE_TYPE;\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
+  read a one-byte data from a IDE port\r
 \r
-  TODO: add return values.\r
+  @param  PciIo  The PCI IO protocol instance\r
+  @param  Port   the IDE Port number \r
 \r
+  return  the one-byte data read from IDE port\r
 **/\r
 UINT8\r
 IDEReadPortB (\r
@@ -49,7 +50,6 @@ IDEReadPortB (
               );\r
   return Data;\r
 }\r
-\r
 /**\r
   Reads multiple words of data from the IDE data port.\r
   Call the IO abstraction once to do the complete read,\r
@@ -109,14 +109,11 @@ IDEReadPortWMultiple (
 }\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Data TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  write a 1-byte data to a specific IDE port\r
 \r
+  @param  PciIo  PCI IO protocol instance\r
+  @param  Port   The IDE port to be writen\r
+  @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 IDEWritePortB (\r
@@ -140,14 +137,11 @@ IDEWritePortB (
 }\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Data TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  write a 1-word data to a specific IDE port\r
 \r
+  @param  PciIo  PCI IO protocol instance\r
+  @param  Port   The IDE port to be writen\r
+  @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 IDEWritePortW (\r
@@ -227,10 +221,6 @@ IDEWritePortWMultiple (
 \r
   gBS->FreePool (WorkingBuffer);\r
 }\r
-\r
-//\r
-// GetIdeRegistersBaseAddr\r
-//\r
 /**\r
   Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,\r
   use fixed addresses. In Native-PCI mode, get base addresses from BARs in\r
@@ -287,9 +277,6 @@ GetIdeRegistersBaseAddr (
   IN  EFI_PCI_IO_PROTOCOL         *PciIo,\r
   OUT IDE_REGISTERS_BASE_ADDR     *IdeRegsBaseAddr\r
   )\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_STATUS  Status;\r
   PCI_TYPE00  PciData;\r
@@ -366,7 +353,6 @@ EFI_STATUS
 ReassignIdeResources (\r
   IN  IDE_BLK_IO_DEV  *IdeDev\r
   )\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_STATUS              Status;\r
   IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
@@ -407,135 +393,6 @@ ReassignIdeResources (
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// DiscoverIdeDevice\r
-//\r
-/**\r
-  Detect if there is disk connected to this port\r
-\r
-  @param  IdeDev The BLK_IO private data which specifies the IDE device.\r
-\r
-**/\r
-EFI_STATUS\r
-DiscoverIdeDevice (\r
-  IN IDE_BLK_IO_DEV *IdeDev\r
-  )\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
-// TODO:    EFI_NOT_FOUND - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_STATUS  LongPhyStatus;\r
-\r
-  //\r
-  // If a channel has not been checked, check it now. Then set it to "checked" state\r
-  // After this step, all devices in this channel have been checked.\r
-  //\r
-  if (!ChannelDeviceDetected) {\r
-    Status = DetectIDEController (IdeDev);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_FOUND;\r
-    }\r
-  }\r
-\r
-  Status = EFI_NOT_FOUND;\r
-\r
-  //\r
-  // Device exists. test if it is an ATA device.\r
-  // Prefer the result from DetectIDEController,\r
-  // if failed, try another device type to handle\r
-  // devices that not follow the spec.\r
-  //\r
-  if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) {\r
-    if (MasterDeviceType == ATA_DEVICE_TYPE) {\r
-      Status = ATAIdentify (IdeDev);\r
-      if (EFI_ERROR (Status)) {\r
-        Status = ATAPIIdentify (IdeDev);\r
-        if (!EFI_ERROR (Status)) {\r
-          MasterDeviceType = ATAPI_DEVICE_TYPE;\r
-        }\r
-      }\r
-    } else {\r
-      Status = ATAPIIdentify (IdeDev);\r
-      if (EFI_ERROR (Status)) {\r
-        Status = ATAIdentify (IdeDev);\r
-        if (!EFI_ERROR (Status)) {\r
-          MasterDeviceType = ATA_DEVICE_TYPE;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) {\r
-    if (SlaveDeviceType == ATA_DEVICE_TYPE) {\r
-      Status = ATAIdentify (IdeDev);\r
-      if (EFI_ERROR (Status)) {\r
-        Status = ATAPIIdentify (IdeDev);\r
-        if (!EFI_ERROR (Status)) {\r
-          SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
-        }\r
-      }\r
-    } else {\r
-      Status = ATAPIIdentify (IdeDev);\r
-      if (EFI_ERROR (Status)) {\r
-        Status = ATAIdentify (IdeDev);\r
-        if (!EFI_ERROR (Status)) {\r
-          SlaveDeviceType = ATA_DEVICE_TYPE;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  //\r
-  // Init Block I/O interface\r
-  //\r
-  LongPhyStatus = AtaEnableLongPhysicalSector (IdeDev);\r
-  if (!EFI_ERROR (LongPhyStatus)) {\r
-    IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;\r
-  } else {\r
-    IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
-  }\r
-  IdeDev->BlkIo.Reset               = IDEBlkIoReset;\r
-  IdeDev->BlkIo.ReadBlocks          = IDEBlkIoReadBlocks;\r
-  IdeDev->BlkIo.WriteBlocks         = IDEBlkIoWriteBlocks;\r
-  IdeDev->BlkIo.FlushBlocks         = IDEBlkIoFlushBlocks;\r
-\r
-  IdeDev->BlkMedia.LogicalPartition = FALSE;\r
-  IdeDev->BlkMedia.WriteCaching     = FALSE;\r
-\r
-  //\r
-  // Init Disk Info interface\r
-  //\r
-  gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID));\r
-  IdeDev->DiskInfo.Inquiry    = IDEDiskInfoInquiry;\r
-  IdeDev->DiskInfo.Identify   = IDEDiskInfoIdentify;\r
-  IdeDev->DiskInfo.SenseData  = IDEDiskInfoSenseData;\r
-  IdeDev->DiskInfo.WhichIde   = IDEDiskInfoWhichIde;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This interface is used to initialize all state data related to the detection of one\r
-  channel.\r
-\r
-  @retval EFI_SUCCESS Completed Successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeIDEChannelData (\r
-  VOID\r
-  )\r
-{\r
-  ChannelDeviceDetected = FALSE;\r
-  MasterDeviceExist = FALSE;\r
-  MasterDeviceType  = 0xff;\r
-  SlaveDeviceExist  = FALSE;\r
-  SlaveDeviceType   = 0xff;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
 /**\r
   This function is called by DiscoverIdeDevice(). It is used for detect\r
   whether the IDE device exists in the specified Channel as the specified\r
@@ -552,20 +409,12 @@ InitializeIDEChannelData (
   register, it is a must to select the current device to accept the command\r
   by set the device number in the Head/Device Register.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev  pointer to IDE_BLK_IO_DEV data structure, used to record all the\r
+                 information of the IDE device.\r
 \r
-  @retval TRUE\r
-  successfully detects device.\r
+  @retval EFI_SUCCESS successfully detects device.\r
 \r
-  @retval FALSE\r
-  any failure during detection process will return this\r
-  value.\r
-\r
-  @note\r
-  TODO:    EFI_SUCCESS - add return value to function comment\r
-  TODO:    EFI_NOT_FOUND - add return value to function comment\r
+  @retval other       any failure during detection process will return this value.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -732,24 +581,140 @@ DetectIDEController (
   ChannelDeviceDetected = TRUE;\r
   return EFI_SUCCESS;\r
 }\r
+/**\r
+  Detect if there is disk attached to this port\r
+\r
+  @param  IdeDev The BLK_IO private data which specifies the IDE device.\r
+\r
+**/\r
+EFI_STATUS\r
+DiscoverIdeDevice (\r
+  IN IDE_BLK_IO_DEV *IdeDev\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STATUS  LongPhyStatus;\r
+\r
+  //\r
+  // If a channel has not been checked, check it now. Then set it to "checked" state\r
+  // After this step, all devices in this channel have been checked.\r
+  //\r
+  if (!ChannelDeviceDetected) {\r
+    Status = DetectIDEController (IdeDev);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  Status = EFI_NOT_FOUND;\r
+\r
+  //\r
+  // Device exists. test if it is an ATA device.\r
+  // Prefer the result from DetectIDEController,\r
+  // if failed, try another device type to handle\r
+  // devices that not follow the spec.\r
+  //\r
+  if ((IdeDev->Device == IdeMaster) && (MasterDeviceExist)) {\r
+    if (MasterDeviceType == ATA_DEVICE_TYPE) {\r
+      Status = ATAIdentify (IdeDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = ATAPIIdentify (IdeDev);\r
+        if (!EFI_ERROR (Status)) {\r
+          MasterDeviceType = ATAPI_DEVICE_TYPE;\r
+        }\r
+      }\r
+    } else {\r
+      Status = ATAPIIdentify (IdeDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = ATAIdentify (IdeDev);\r
+        if (!EFI_ERROR (Status)) {\r
+          MasterDeviceType = ATA_DEVICE_TYPE;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if ((IdeDev->Device == IdeSlave) && (SlaveDeviceExist)) {\r
+    if (SlaveDeviceType == ATA_DEVICE_TYPE) {\r
+      Status = ATAIdentify (IdeDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = ATAPIIdentify (IdeDev);\r
+        if (!EFI_ERROR (Status)) {\r
+          SlaveDeviceType = ATAPI_DEVICE_TYPE;\r
+        }\r
+      }\r
+    } else {\r
+      Status = ATAPIIdentify (IdeDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = ATAIdentify (IdeDev);\r
+        if (!EFI_ERROR (Status)) {\r
+          SlaveDeviceType = ATA_DEVICE_TYPE;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  //\r
+  // Init Block I/O interface\r
+  //\r
+  LongPhyStatus = AtaEnableLongPhysicalSector (IdeDev);\r
+  if (!EFI_ERROR (LongPhyStatus)) {\r
+    IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;\r
+  } else {\r
+    IdeDev->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
+  }\r
+  IdeDev->BlkIo.Reset               = IDEBlkIoReset;\r
+  IdeDev->BlkIo.ReadBlocks          = IDEBlkIoReadBlocks;\r
+  IdeDev->BlkIo.WriteBlocks         = IDEBlkIoWriteBlocks;\r
+  IdeDev->BlkIo.FlushBlocks         = IDEBlkIoFlushBlocks;\r
+\r
+  IdeDev->BlkMedia.LogicalPartition = FALSE;\r
+  IdeDev->BlkMedia.WriteCaching     = FALSE;\r
 \r
+  //\r
+  // Init Disk Info interface\r
+  //\r
+  gBS->CopyMem (&IdeDev->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid, sizeof (EFI_GUID));\r
+  IdeDev->DiskInfo.Inquiry    = IDEDiskInfoInquiry;\r
+  IdeDev->DiskInfo.Identify   = IDEDiskInfoIdentify;\r
+  IdeDev->DiskInfo.SenseData  = IDEDiskInfoSenseData;\r
+  IdeDev->DiskInfo.WhichIde   = IDEDiskInfoWhichIde;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This interface is used to initialize all state data related to the detection of one\r
+  channel.\r
+\r
+  @retval EFI_SUCCESS Completed Successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeIDEChannelData (\r
+  VOID\r
+  )\r
+{\r
+  ChannelDeviceDetected = FALSE;\r
+  MasterDeviceExist = FALSE;\r
+  MasterDeviceType  = 0xff;\r
+  SlaveDeviceExist  = FALSE;\r
+  SlaveDeviceType   = 0xff;\r
+  return EFI_SUCCESS;\r
+}\r
 /**\r
   This function is used to poll for the DRQ bit clear in the Status\r
   Register. DRQ is cleared when the device is finished transferring data.\r
   So this function is called after data transfer is finished.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev                 pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                                to record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds  used to designate the timeout for the DRQ clear.\r
 \r
-  @param[in] TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ clear.\r
+  @retval EFI_SUCCESS           DRQ bit clear within the time out.\r
 \r
-  @retval EFI_SUCCESS\r
-  DRQ bit clear within the time out.\r
-\r
-  @retval EFI_TIMEOUT\r
-  DRQ bit not clear within the time out.\r
+  @retval EFI_TIMEOUT           DRQ bit not clear within the time out.\r
 \r
   @note\r
   Read Status Register will clear interrupt status.\r
@@ -760,11 +725,6 @@ DRQClear (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
-// TODO:    EFI_ABORTED - add return value to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   StatusRegister;\r
@@ -805,28 +765,21 @@ DRQClear (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
   This function is used to poll for the DRQ bit clear in the Alternate\r
   Status Register. DRQ is cleared when the device is finished\r
   transferring data. So this function is called after data transfer\r
   is finished.\r
 \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                               to record all the information of the IDE device.\r
 \r
-  @param[in] TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ clear.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ clear.\r
 \r
-  @retval EFI_SUCCESS\r
-  DRQ bit clear within the time out.\r
+  @retval EFI_SUCCESS          DRQ bit clear within the time out.\r
 \r
-  @retval EFI_TIMEOUT\r
-  DRQ bit not clear within the time out.\r
-\r
-  @note\r
-  Read Alternate Status Register will not clear interrupt status.\r
+  @retval EFI_TIMEOUT          DRQ bit not clear within the time out.\r
+  @note   Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -834,11 +787,6 @@ DRQClear2 (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
-// TODO:    EFI_ABORTED - add return value to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   AltRegister;\r
@@ -887,24 +835,15 @@ DRQClear2 (
   is called after the command is sent to the device and before required\r
   data is transferred.\r
 \r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure,used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] UINTN     IN    TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
-\r
-  @retval EFI_SUCCESS\r
-  DRQ bit set within the time out.\r
-\r
-  @retval EFI_TIMEOUT\r
-  DRQ bit not set within the time out.\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure,used to\r
+                               record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @retval EFI_ABORTED\r
-  DRQ bit not set caused by the command abort.\r
+  @retval EFI_SUCCESS          DRQ bit set within the time out.\r
+  @retval EFI_TIMEOUT          DRQ bit not set within the time out.\r
+  @retval EFI_ABORTED          DRQ bit not set caused by the command abort.\r
 \r
-  @note\r
-  Read Status Register will clear interrupt status.\r
+  @note  Read Status Register will clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -912,10 +851,6 @@ DRQReady (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   StatusRegister;\r
@@ -957,31 +892,20 @@ DRQReady (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
 /**\r
-  This function is used to poll for the DRQ bit set in the\r
-  Alternate Status Register. DRQ is set when the device is ready to\r
-  transfer data. So this function is called after the command\r
-  is sent to the device and before required data is transferred.\r
-\r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] UINTN     IN    TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
-\r
-  @retval EFI_SUCCESS\r
-  DRQ bit set within the time out.\r
+  This function is used to poll for the DRQ bit set in the Alternate Status Register.\r
+  DRQ is set when the device is ready to transfer data. So this function is called after \r
+  the command is sent to the device and before required data is transferred.\r
 \r
-  @retval EFI_TIMEOUT\r
-  DRQ bit not set within the time out.\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used to \r
+                               record all the information of the IDE device.\r
 \r
-  @retval EFI_ABORTED\r
-  DRQ bit not set caused by the command abort.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @note\r
-  Read Alternate Status Register will not clear interrupt status.\r
+  @retval EFI_SUCCESS           DRQ bit set within the time out.\r
+  @retval EFI_TIMEOUT           DRQ bit not set within the time out.\r
+  @retval EFI_ABORTED           DRQ bit not set caused by the command abort.\r
+  @note  Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -989,10 +913,6 @@ DRQReady2 (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   AltRegister;\r
@@ -1036,36 +956,23 @@ DRQReady2 (
 }\r
 \r
 /**\r
-  This function is used to poll for the BSY bit clear in the\r
-  Status Register. BSY is clear when the device is not busy.\r
-  Every command must be sent after device is not busy.\r
-\r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  This function is used to poll for the BSY bit clear in the Status Register. BSY\r
+  is clear when the device is not busy. Every command must be sent after device is not busy.\r
 \r
-  @param[in] UINTN     IN    TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                               to record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @retval EFI_SUCCESS\r
-  BSY bit clear within the time out.\r
-\r
-  @retval EFI_TIMEOUT\r
-  BSY bit not clear within the time out.\r
-\r
-  @note\r
-  Read Status Register will clear interrupt status.\r
+  @retval EFI_SUCCESS          BSY bit clear within the time out.\r
+  @retval EFI_TIMEOUT          BSY bit not clear within the time out.\r
 \r
+  @note Read Status Register will clear interrupt status.\r
 **/\r
 EFI_STATUS\r
 WaitForBSYClear (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   StatusRegister;\r
@@ -1093,29 +1000,18 @@ WaitForBSYClear (
 \r
   return EFI_SUCCESS;\r
 }\r
-//\r
-// WaitForBSYClear2\r
-//\r
 /**\r
-  This function is used to poll for the BSY bit clear in the\r
-  Alternate Status Register. BSY is clear when the device is not busy.\r
-  Every command must be sent after device is not busy.\r
-\r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  This function is used to poll for the BSY bit clear in the Alternate Status Register. \r
+  BSY is clear when the device is not busy. Every command must be sent after device is \r
+  not busy.\r
 \r
-  @param[in] UINTN     IN    TimeoutInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
+  @param IdeDev               pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                              all the information of the IDE device.\r
+  @paramTimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @retval EFI_SUCCESS\r
-  BSY bit clear within the time out.\r
-\r
-  @retval EFI_TIMEOUT\r
-  BSY bit not clear within the time out.\r
-\r
-  @note\r
-  Read Alternate Status Register will not clear interrupt status.\r
+  @retval EFI_SUCCESS         BSY bit clear within the time out.\r
+  @retval EFI_TIMEOUT         BSY bit not clear within the time out.\r
+  @note   Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1123,10 +1019,6 @@ WaitForBSYClear2 (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           TimeoutInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    TimeoutInMilliSeconds - add argument and description to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   AltRegister;\r
@@ -1150,43 +1042,25 @@ WaitForBSYClear2 (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-//\r
-// DRDYReady\r
-//\r
 /**\r
-  This function is used to poll for the DRDY bit set in the\r
-  Status Register. DRDY bit is set when the device is ready\r
-  to accept command. Most ATA commands must be sent after\r
-  DRDY set except the ATAPI Packet Command.\r
-\r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] UINTN     IN    DelayInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
-\r
-  @retval EFI_SUCCESS\r
-  DRDY bit set within the time out.\r
+  This function is used to poll for the DRDY bit set in the Status Register. DRDY\r
+  bit is set when the device is ready to accept command. Most ATA commands must be \r
+  sent after DRDY set except the ATAPI Packet Command.\r
 \r
-  @retval EFI_TIMEOUT\r
-  DRDY bit not set within the time out.\r
+  @param IdeDev               pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                              to record all the information of the IDE device.\r
+  @param DelayInMilliSeconds  used to designate the timeout for the DRQ ready.\r
 \r
-  @note\r
-  Read Status Register will clear interrupt status.\r
+  @retval EFI_SUCCESS         DRDY bit set within the time out.\r
+  @retval EFI_TIMEOUT         DRDY bit not set within the time out.\r
 \r
+  @note  Read Status Register will clear interrupt status.\r
 **/\r
 EFI_STATUS\r
 DRDYReady (\r
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           DelayInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    DelayInMilliSeconds - add argument and description to function comment\r
-// TODO:    EFI_ABORTED - add return value to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   StatusRegister;\r
@@ -1221,31 +1095,19 @@ DRDYReady (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-//\r
-// DRDYReady2\r
-//\r
 /**\r
-  This function is used to poll for the DRDY bit set in the\r
-  Alternate Status Register. DRDY bit is set when the device is ready\r
-  to accept command. Most ATA commands must be sent after\r
-  DRDY set except the ATAPI Packet Command.\r
-\r
-  @param[in] IDE_BLK_IO_DEV  IN    *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
+  This function is used to poll for the DRDY bit set in the Alternate Status Register. \r
+  DRDY bit is set when the device is ready to accept command. Most ATA commands must \r
+  be sent after DRDY set except the ATAPI Packet Command.\r
 \r
-  @param[in] UINTN     IN    DelayInMilliSeconds\r
-  used to designate the timeout for the DRQ ready.\r
+  @param IdeDev              pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                             to record all the information of the IDE device.\r
+  @param DelayInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @retval EFI_SUCCESS\r
-  DRDY bit set within the time out.\r
+  @retval EFI_SUCCESS      DRDY bit set within the time out.\r
+  @retval EFI_TIMEOUT      DRDY bit not set within the time out.\r
 \r
-  @retval EFI_TIMEOUT\r
-  DRDY bit not set within the time out.\r
-\r
-  @note\r
-  Read Alternate Status Register will clear interrupt status.\r
+  @note  Read Alternate Status Register will clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1253,11 +1115,6 @@ DRDYReady2 (
   IN  IDE_BLK_IO_DEV  *IdeDev,\r
   IN  UINTN           DelayInMilliSeconds\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO:    IdeDev - add argument and description to function comment\r
-// TODO:    DelayInMilliSeconds - add argument and description to function comment\r
-// TODO:    EFI_ABORTED - add return value to function comment\r
 {\r
   UINT32  Delay;\r
   UINT8   AltRegister;\r
@@ -1292,57 +1149,10 @@ DRDYReady2 (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-//\r
-// SwapStringChars\r
-//\r
-/**\r
-  This function is a helper function used to change the char order in a\r
-  string. It is designed specially for the PrintAtaModuleName() function.\r
-  After the IDE device is detected, the IDE driver gets the device module\r
-  name by sending ATA command called ATA Identify Command or ATAPI\r
-  Identify Command to the specified IDE device. The module name returned\r
-  is a string of ASCII characters: the first character is bit8--bit15\r
-  of the first word, the second character is BIT0--bit7 of the first word\r
-  and so on. Thus the string can not be print directly before it is\r
-  preprocessed by this func to change the order of characters in\r
-  each word in the string.\r
-\r
-  @param[in] CHAR8 IN    *Destination\r
-  Indicates the destination string.\r
-\r
-  @param[in] CHAR8 IN    *Source\r
-  Indicates the source string.\r
-\r
-  @param[in] UINT8 IN    Size\r
-  the length of the string\r
-\r
-**/\r
-VOID\r
-SwapStringChars (\r
-  IN CHAR8  *Destination,\r
-  IN CHAR8  *Source,\r
-  IN UINT32 Size\r
-  )\r
-{\r
-  UINT32  Index;\r
-  CHAR8   Temp;\r
-\r
-  for (Index = 0; Index < Size; Index += 2) {\r
-\r
-    Temp                    = Source[Index + 1];\r
-    Destination[Index + 1]  = Source[Index];\r
-    Destination[Index]      = Temp;\r
-  }\r
-}\r
-\r
-//\r
-// ReleaseIdeResources\r
-//\r
 /**\r
   Release resources of an IDE device before stopping it.\r
 \r
-  @param[in] *IdeBlkIoDevice  Standard IDE device private data structure\r
+  @param IdeBlkIoDevice  Standard IDE device private data structure\r
 \r
 **/\r
 VOID\r
@@ -1401,16 +1211,11 @@ ReleaseIdeResources (
 \r
   return ;\r
 }\r
-\r
-//\r
-// SetDeviceTransferMode\r
-//\r
 /**\r
   Set the calculated Best transfer mode to a detected device\r
 \r
-  @param[in] *IdeDev       Standard IDE device private data structure\r
-  @param[in] *TransferMode The device transfer mode to be set\r
-\r
+  @param IdeDev       Standard IDE device private data structure\r
+  @param TransferMode The device transfer mode to be set\r
   @return Set transfer mode Command execute status.\r
 \r
 **/\r
@@ -1419,7 +1224,6 @@ SetDeviceTransferMode (
   IN IDE_BLK_IO_DEV       *IdeDev,\r
   IN ATA_TRANSFER_MODE    *TransferMode\r
   )\r
-// TODO: function comment is missing 'Routine Description:'\r
 {\r
   EFI_STATUS  Status;\r
   UINT8       DeviceSelect;\r
@@ -1445,229 +1249,11 @@ SetDeviceTransferMode (
 \r
   return Status;\r
 }\r
-\r
-/**\r
-  Send ATA command into device with NON_DATA protocol\r
-\r
-  @param  IdeDev Standard IDE device private data structure\r
-  @param  AtaCommand The ATA command to be sent\r
-  @param  Device The value in Device register\r
-  @param  Feature The value in Feature register\r
-  @param  SectorCount The value in SectorCount register\r
-  @param  LbaLow The value in LBA_LOW register\r
-  @param  LbaMiddle The value in LBA_MIDDLE register\r
-  @param  LbaHigh The value in LBA_HIGH register\r
-\r
-  @retval  EFI_SUCCESS Reading succeed\r
-  @retval  EFI_ABORTED Command failed\r
-  @retval  EFI_DEVICE_ERROR Device status error.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandIn (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT8           Feature,\r
-  IN  UINT8           SectorCount,\r
-  IN  UINT8           LbaLow,\r
-  IN  UINT8           LbaMiddle,\r
-  IN  UINT8           LbaHigh\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT8       StatusRegister;\r
-\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
-  //\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
-    );\r
-\r
-  //\r
-  // ATA commands for ATA device must be issued when DRDY is set\r
-  //\r
-  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Pass parameter into device register block\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMiddle);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
-  //\r
-  // Send command via Command Register\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
-  //\r
-  // Wait for command completion\r
-  // For ATAPI_SMART_CMD, we may need more timeout to let device\r
-  // adjust internal states.\r
-  //\r
-  if (AtaCommand == ATA_CMD_SMART) {\r
-    Status = WaitForBSYClear (IdeDev, ATASMARTTIMEOUT);\r
-  } else {\r
-    Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-  if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
-    //\r
-    // Failed to execute command, abort operation\r
-    //\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Send ATA Ext command into device with NON_DATA protocol\r
-\r
-  @param  IdeDev Standard IDE device private data structure\r
-  @param  AtaCommand The ATA command to be sent\r
-  @param  Device The value in Device register\r
-  @param  Feature The value in Feature register\r
-  @param  SectorCount The value in SectorCount register\r
-  @param  LbaAddress The LBA address in 48-bit mode\r
-\r
-  @retval  EFI_SUCCESS Reading succeed\r
-  @retval  EFI_ABORTED Command failed\r
-  @retval  EFI_DEVICE_ERROR Device status error.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaNonDataCommandInExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT16          Feature,\r
-  IN  UINT16          SectorCount,\r
-  IN  EFI_LBA         LbaAddress\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT8       StatusRegister;\r
-  UINT8       SectorCount8;\r
-  UINT8       Feature8;\r
-  UINT8       LbaLow;\r
-  UINT8       LbaMid;\r
-  UINT8       LbaHigh;\r
-\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
-  //\r
-  IDEWritePortB (\r
-    IdeDev->PciIo,\r
-    IdeDev->IoPort->Head,\r
-    (UINT8) ((IdeDev->Device << 4) | 0xe0)\r
-    );\r
-\r
-  //\r
-  // ATA commands for ATA device must be issued when DRDY is set\r
-  //\r
-  Status = DRDYReady (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Pass parameter into device register block\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
-  //\r
-  // Fill the feature register, which is a two-byte FIFO. Need write twice.\r
-  //\r
-  Feature8 = (UINT8) (Feature >> 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
-  Feature8 = (UINT8) Feature;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);\r
-\r
-  //\r
-  // Fill the sector count register, which is a two-byte FIFO. Need write twice.\r
-  //\r
-  SectorCount8 = (UINT8) (SectorCount >> 8);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
-  SectorCount8 = (UINT8) SectorCount;\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);\r
-\r
-  //\r
-  // Fill the start LBA registers, which are also two-byte FIFO\r
-  //\r
-  LbaLow  = (UINT8) RShiftU64 (LbaAddress, 24);\r
-  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 32);\r
-  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
-  LbaLow  = (UINT8) LbaAddress;\r
-  LbaMid  = (UINT8) RShiftU64 (LbaAddress, 8);\r
-  LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);\r
-\r
-  //\r
-  // Send command via Command Register\r
-  //\r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);\r
-\r
-  //\r
-  // Wait for command completion\r
-  //\r
-  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
-  if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
-    //\r
-    // Failed to execute command, abort operation\r
-    //\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// SetDriveParameters\r
-//\r
 /**\r
   Set drive parameters for devices not support PACKETS command\r
 \r
-  @param[in] IdeDev       Standard IDE device private data structure\r
-  @param[in] DriveParameters The device parameters to be set into the disk\r
-\r
+  @param IdeDev          Standard IDE device private data structure\r
+  @param DriveParameters The device parameters to be set into the disk\r
   @return SetParameters Command execute status.\r
 \r
 **/\r
@@ -1714,12 +1300,11 @@ SetDriveParameters (
 }\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
+  Enable Interrupt on IDE controller\r
 \r
-  @retval  EFI_SUCCESS TODO: Add description for return value.\r
+  @param  IdeDev   Standard IDE device private data structure\r
 \r
+  @retval  EFI_SUCCESS Enable Interrupt successfully\r
 **/\r
 EFI_STATUS\r
 EnableInterrupt (\r
@@ -1736,99 +1321,3 @@ EnableInterrupt (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-/**\r
-  Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
-\r
-  @param[in]  Event   Pointer to this event\r
-  @param[in]  Context Event hanlder 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
-  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
index 89bc191ab9b2fd1ef555af6040141900bc77272d..b919457bb54e633733defce4cf9e0ac3dbedaec3 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
   Header file for IDE Bus Driver, containing the helper functions'\r
-  entire prototype.\r
+  prototype.\r
 \r
   Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
   All rights reserved. This program and the accompanying materials\r
 // Helper functions Prototype\r
 //\r
 /**\r
-  TODO: Add function description\r
+  read a one-byte data from a IDE port\r
 \r
-  @param  This TODO: add argument description\r
-  @param  Controller TODO: add argument description\r
-  @param  Handle TODO: add argument description\r
-\r
-  TODO: add return values.\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
-/**\r
-  TODO: Add function description\r
-\r
-  @param  Controller TODO: add argument description\r
-  @param  PciIo TODO: add argument description\r
-  @param  ParentDevicePath TODO: add argument description\r
-  @param  RemainingDevicePath TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-EnableIdeDevice (\r
-  IN EFI_HANDLE                          Controller,\r
-  IN EFI_PCI_IO_PROTOCOL                 *PciIo,\r
-  IN EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath,\r
-  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param  PciIo  The PCI IO protocol instance\r
+  @param  Port   the IDE Port number \r
 \r
+  return  the one-byte data read from IDE port\r
 **/\r
 UINT8\r
 IDEReadPortB (\r
@@ -76,14 +39,14 @@ IDEReadPortB (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Count TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
+  Reads multiple words of data from the IDE data port.\r
+  Call the IO abstraction once to do the complete read,\r
+  not one word at a time\r
 \r
-  TODO: add return values.\r
+  @param  PciIo Pointer to the EFI_PCI_IO instance\r
+  @param  Port IO port to read\r
+  @param  Count No. of UINT16's to read\r
+  @param  Buffer Pointer to the data buffer for read\r
 \r
 **/\r
 VOID\r
@@ -95,14 +58,11 @@ IDEReadPortWMultiple (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Data TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  write a 1-byte data to a specific IDE port\r
 \r
+  @param  PciIo  PCI IO protocol instance\r
+  @param  Port   The IDE port to be writen\r
+  @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 IDEWritePortB (\r
@@ -112,14 +72,11 @@ IDEWritePortB (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Data TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  write a 1-word data to a specific IDE port\r
 \r
+  @param  PciIo  PCI IO protocol instance\r
+  @param  Port   The IDE port to be writen\r
+  @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 IDEWritePortW (\r
@@ -129,14 +86,14 @@ IDEWritePortW (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Port TODO: add argument description\r
-  @param  Count TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
+  Write multiple words of data to the IDE data port.\r
+  Call the IO abstraction once to do the complete read,\r
+  not one word at a time\r
 \r
-  TODO: add return values.\r
+  @param  PciIo Pointer to the EFI_PCI_IO instance\r
+  @param  Port IO port to read\r
+  @param  Count No. of UINT16's to read\r
+  @param  Buffer Pointer to the data buffer for read\r
 \r
 **/\r
 VOID\r
@@ -148,12 +105,54 @@ IDEWritePortWMultiple (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,\r
+  use fixed addresses. In Native-PCI mode, get base addresses from BARs in\r
+  the PCI IDE controller's Configuration Space.\r
 \r
-  @param  PciIo TODO: add argument description\r
-  @param  IdeRegsBaseAddr TODO: add argument description\r
+  The steps to get IDE IO port registers' base addresses for each channel\r
+  as follows:\r
 \r
-  TODO: add return values.\r
+  1. Examine the Programming Interface byte of the Class Code fields in PCI IDE\r
+  controller's Configuration Space to determine the operating mode.\r
+\r
+  2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.\r
+  <pre>\r
+  ___________________________________________\r
+  |           | Command Block | Control Block |\r
+  |  Channel  |   Registers   |   Registers   |\r
+  |___________|_______________|_______________|\r
+  |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |\r
+  |___________|_______________|_______________|\r
+  | Secondary |  170h - 177h  |  376h - 377h  |\r
+  |___________|_______________|_______________|\r
+\r
+  Table 1. Compatibility resource mappings\r
+  </pre>\r
+\r
+  b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
+  in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
+  <pre>\r
+  ___________________________________________________\r
+  |           |   Command Block   |   Control Block   |\r
+  |  Channel  |     Registers     |     Registers     |\r
+  |___________|___________________|___________________|\r
+  |  Primary  | BAR at offset 0x10| BAR at offset 0x14|\r
+  |___________|___________________|___________________|\r
+  | Secondary | BAR at offset 0x18| BAR at offset 0x1C|\r
+  |___________|___________________|___________________|\r
+\r
+  Table 2. BARs for Register Mapping\r
+  </pre>\r
+  @note Refer to Intel ICH4 datasheet, Control Block Offset: 03F4h for\r
+  primary, 0374h for secondary. So 2 bytes extra offset should be\r
+  added to the base addresses read from BARs.\r
+\r
+  For more details, please refer to PCI IDE Controller Specification and Intel\r
+  ICH4 Datasheet.\r
+\r
+  @param  PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance\r
+  @param  IdeRegsBaseAddr Pointer to IDE_REGISTERS_BASE_ADDR to\r
+  receive IDE IO port registers' base addresses\r
 \r
 **/\r
 EFI_STATUS\r
@@ -163,11 +162,12 @@ GetIdeRegistersBaseAddr (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to requery IDE resources. The IDE controller will\r
+  probably switch between native and legacy modes during the EFI->CSM->OS\r
+  transfer. We do this everytime before an BlkIo operation to ensure its\r
+  succeess.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param  IdeDev The BLK_IO private data which specifies the IDE device\r
 \r
 **/\r
 EFI_STATUS\r
@@ -176,11 +176,9 @@ ReassignIdeResources (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
+  Detect if there is disk attached to this port\r
 \r
-  TODO: add return values.\r
+  @param  IdeDev The BLK_IO private data which specifies the IDE device.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -201,25 +199,20 @@ InitializeIDEChannelData (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRQ bit clear in the Status\r
+  Register. DRQ is cleared when the device is finished transferring data.\r
+  So this function is called after data transfer is finished.\r
 \r
-  @param  IdeDev TODO: add argument description\r
+  @param IdeDev                 pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                                to record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds  used to designate the timeout for the DRQ clear.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS           DRQ bit clear within the time out.\r
 \r
-**/\r
-EFI_STATUS\r
-DetectIDEController (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  );\r
+  @retval EFI_TIMEOUT           DRQ bit not clear within the time out.\r
 \r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @note\r
+  Read Status Register will clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -229,12 +222,21 @@ DRQClear (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRQ bit clear in the Alternate\r
+  Status Register. DRQ is cleared when the device is finished\r
+  transferring data. So this function is called after data transfer\r
+  is finished.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                               to record all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ clear.\r
+\r
+  @retval EFI_SUCCESS          DRQ bit clear within the time out.\r
+\r
+  @retval EFI_TIMEOUT          DRQ bit not clear within the time out.\r
+  @note\r
+  Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -244,12 +246,21 @@ DRQClear2 (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRQ bit set in the\r
+  Status Register.\r
+  DRQ is set when the device is ready to transfer data. So this function\r
+  is called after the command is sent to the device and before required\r
+  data is transferred.\r
+\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure,used to\r
+                               record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
+  @retval EFI_SUCCESS          DRQ bit set within the time out.\r
+  @retval EFI_TIMEOUT          DRQ bit not set within the time out.\r
+  @retval EFI_ABORTED          DRQ bit not set caused by the command abort.\r
 \r
-  TODO: add return values.\r
+  @note  Read Status Register will clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -259,12 +270,19 @@ DRQReady (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRQ bit set in the Alternate Status Register.\r
+  DRQ is set when the device is ready to transfer data. So this function is called after \r
+  the command is sent to the device and before required data is transferred.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used to \r
+                               record all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
+\r
+  @retval EFI_SUCCESS           DRQ bit set within the time out.\r
+  @retval EFI_TIMEOUT           DRQ bit not set within the time out.\r
+  @retval EFI_ABORTED           DRQ bit not set caused by the command abort.\r
+  @note  Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -274,13 +292,17 @@ DRQReady2 (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the BSY bit clear in the Status Register. BSY\r
+  is clear when the device is not busy. Every command must be sent after device is not busy.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
+  @param IdeDev                pointer pointing to IDE_BLK_IO_DEV data structure, used \r
+                               to record all the information of the IDE device.\r
+  @param TimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS          BSY bit clear within the time out.\r
+  @retval EFI_TIMEOUT          BSY bit not clear within the time out.\r
 \r
+  @note Read Status Register will clear interrupt status.\r
 **/\r
 EFI_STATUS\r
 WaitForBSYClear (\r
@@ -289,12 +311,17 @@ WaitForBSYClear (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the BSY bit clear in the Alternate Status Register. \r
+  BSY is clear when the device is not busy. Every command must be sent after device is \r
+  not busy.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  TimeoutInMilliSeconds TODO: add argument description\r
+  @param IdeDev               pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                              all the information of the IDE device.\r
+  @paramTimeoutInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS         BSY bit clear within the time out.\r
+  @retval EFI_TIMEOUT         BSY bit not clear within the time out.\r
+  @note   Read Alternate Status Register will not clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -304,13 +331,18 @@ WaitForBSYClear2 (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRDY bit set in the Status Register. DRDY\r
+  bit is set when the device is ready to accept command. Most ATA commands must be \r
+  sent after DRDY set except the ATAPI Packet Command.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  DelayInMilliSeconds TODO: add argument description\r
+  @param IdeDev               pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                              to record all the information of the IDE device.\r
+  @param DelayInMilliSeconds  used to designate the timeout for the DRQ ready.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS         DRDY bit set within the time out.\r
+  @retval EFI_TIMEOUT         DRDY bit not set within the time out.\r
 \r
+  @note  Read Status Register will clear interrupt status.\r
 **/\r
 EFI_STATUS\r
 DRDYReady (\r
@@ -319,12 +351,18 @@ DRDYReady (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to poll for the DRDY bit set in the Alternate Status Register. \r
+  DRDY bit is set when the device is ready to accept command. Most ATA commands must \r
+  be sent after DRDY set except the ATAPI Packet Command.\r
+\r
+  @param IdeDev              pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                             to record all the information of the IDE device.\r
+  @param DelayInMilliSeconds used to designate the timeout for the DRQ ready.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  DelayInMilliSeconds TODO: add argument description\r
+  @retval EFI_SUCCESS      DRDY bit set within the time out.\r
+  @retval EFI_TIMEOUT      DRDY bit not set within the time out.\r
 \r
-  TODO: add return values.\r
+  @note  Read Alternate Status Register will clear interrupt status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -333,32 +371,26 @@ DRDYReady2 (
   IN  UINTN           DelayInMilliSeconds\r
   );\r
 \r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  Destination TODO: add argument description\r
-  @param  Source TODO: add argument description\r
-  @param  Size TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-VOID\r
-SwapStringChars (\r
-  IN CHAR8  *Destination,\r
-  IN CHAR8  *Source,\r
-  IN UINT32 Size\r
-  );\r
-\r
 //\r
 //  ATA device functions' prototype\r
 //\r
 /**\r
-  TODO: Add function description\r
+  Sends out an ATA Identify Command to the specified device.\r
+\r
+  This function is called by DiscoverIdeDevice() during its device\r
+  identification. It sends out the ATA Identify Command to the\r
+  specified device. Only ATA device responses to this command. If\r
+  the command succeeds, it returns the Identify data structure which\r
+  contains information about the device. This function extracts the\r
+  information it needs to fill the IDE_BLK_IO_DEV data structure,\r
+  including device type, media block size, media capacity, and etc.\r
 \r
-  @param  IdeDev TODO: add argument description\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure,used to record \r
+                 all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS      Identify ATA device successfully.\r
+  @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.\r
+  @note  parameter IdeDev will be updated in this function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -367,32 +399,31 @@ ATAIdentify (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.\r
 \r
+  @param  IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                   all the information of the IDE device.\r
 **/\r
 VOID\r
 PrintAtaModuleName (\r
   IN  IDE_BLK_IO_DEV  *IdeDev\r
   );\r
-\r
 /**\r
-  TODO: Add function description\r
+  This function is used to send out ATA commands conforms to the PIO Data In Protocol.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Head TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  SectorNumber TODO: add argument description\r
-  @param  CylinderLsb TODO: add argument description\r
-  @param  CylinderMsb TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used to record \r
+                      all the information of the IDE device.\r
+  @param Buffer       buffer contained data transferred from device to host.\r
+  @param ByteCount    data size in byte unit of the buffer.\r
+  @param AtaCommand   value of the Command Register\r
+  @param Head         value of the Head/Device Register\r
+  @param SectorCount  value of the Sector Count Register\r
+  @param SectorNumber value of the Sector Number Register\r
+  @param CylinderLsb  value of the low byte of the Cylinder Register\r
+  @param CylinderMsb  value of the high byte of the Cylinder Register\r
+  \r
+  @retval EFI_SUCCESS      send out the ATA command and device send required data successfully.\r
+  @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -409,19 +440,23 @@ AtaPioDataIn (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to send out ATA commands conforms to the\r
+  PIO Data Out Protocol.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Head TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  SectorNumber TODO: add argument description\r
-  @param  CylinderLsb TODO: add argument description\r
-  @param  CylinderMsb TODO: add argument description\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param *Buffer      buffer contained data transferred from host to device.\r
+  @param ByteCount    data size in byte unit of the buffer.\r
+  @param AtaCommand   value of the Command Register\r
+  @param Head         value of the Head/Device Register\r
+  @param SectorCount  value of the Sector Count Register\r
+  @param SectorNumber value of the Sector Number Register\r
+  @param CylinderLsb  value of the low byte of the Cylinder Register\r
+  @param CylinderMsb  value of the high byte of the Cylinder Register\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS      send out the ATA command and device received required\r
+                           data successfully.\r
+  @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -438,11 +473,15 @@ AtaPioDataOut (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to analyze the Status Register and print out\r
+  some debug information and if there is ERR bit set in the Status\r
+  Register, the Error Register's value is also be parsed and print out.\r
 \r
-  @param  IdeDev TODO: add argument description\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure, used to \r
+                 record all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS       No err information in the Status Register.\r
+  @retval EFI_DEVICE_ERROR  Any err information in the Status Register.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -451,50 +490,23 @@ CheckErrorStatus (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to implement the Soft Reset on the specified device. But,\r
+  the ATA Soft Reset mechanism is so strong a reset method that it will force \r
+  resetting on both devices connected to the same cable.\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
+  It is called by IdeBlkIoReset(), a interface function of Block\r
+  I/O protocol.\r
 \r
-  TODO: add return values.\r
+  This function can also be used by the ATAPI device to perform reset when\r
+  ATAPI Reset command is failed.\r
 \r
-**/\r
-EFI_STATUS\r
-AtaReadSectors (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         Lba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  BufferData TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectors (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *BufferData,\r
-  IN  EFI_LBA         Lba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param IdeDev  pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                 all the information of the IDE device.\r
+  @retval EFI_SUCCESS       Soft reset completes successfully.\r
+  @retval EFI_DEVICE_ERROR  Any step during the reset process is failed.\r
 \r
+  @note  The registers initial values after ATA soft reset are different\r
+         to the ATA device and ATAPI device.\r
 **/\r
 EFI_STATUS\r
 AtaSoftReset (\r
@@ -502,15 +514,30 @@ AtaSoftReset (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is the ATA implementation for ReadBlocks in the\r
+  Block I/O Protocol interface.\r
+\r
+  @param IdeBlkIoDevice Indicates the calling context.\r
+  @param MediaId        The media id that the read request is for.\r
+  @param LBA            The starting logical block address to read from on the device.\r
+  @param BufferSize     The size of the Buffer in bytes. This must be a  multiple\r
+                        of the intrinsic block size of the device.\r
 \r
-  @param  IdeBlkIoDevice TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
+  @param Buffer         A pointer to the destination buffer for the data. The caller\r
+                        is responsible for either having implicit or explicit ownership\r
+                        of the memory that data is read into.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS          Read Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR     Read Blocks failed.\r
+  @retval EFI_NO_MEDIA         There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE  The BufferSize parameter is not a multiple of the\r
+                               intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER  The read request contains LBAs that are not valid,\r
+                                 or the data buffer is not valid.\r
+\r
+  @note If Read Block error because of device error, this function will call\r
+        AtaSoftReset() function to reset device.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -523,16 +550,30 @@ AtaBlkIoReadBlocks (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is the ATA implementation for WriteBlocks in the\r
+  Block I/O Protocol interface.\r
+\r
+  @param IdeBlkIoDevice  Indicates the calling context.\r
+  @param MediaId         The media id that the write request is for.\r
+  @param LBA             The starting logical block address to write onto the device.\r
+  @param BufferSize      The size of the Buffer in bytes. This must be a multiple\r
+                         of the intrinsic block size of the device.\r
+  @param Buffer          A pointer to the source buffer for the data.The caller\r
+                         is responsible for either having implicit or explicit \r
+                         ownership of the memory that data is written from.\r
 \r
-  @param  IdeBlkIoDevice TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
+  @retval EFI_SUCCESS       Write Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR  Write Blocks failed.\r
+  @retval EFI_NO_MEDIA      There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE  The MediaId is not for the current media.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
+                                or the data buffer is not valid.\r
 \r
+  @note If Write Block error because of device error, this function will call\r
+        AtaSoftReset() function to reset device.\r
 **/\r
 EFI_STATUS\r
 AtaBlkIoWriteBlocks (\r
@@ -543,16 +584,35 @@ AtaBlkIoWriteBlocks (
   OUT VOID            *Buffer\r
   );\r
 \r
-//\r
-// ATAPI device functions' prototype\r
-//\r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
+  This function is called by DiscoverIdeDevice() during its device\r
+  identification.\r
+  Its main purpose is to get enough information for the device media\r
+  to fill in the Media data structure of the Block I/O Protocol interface.\r
+\r
+  There are 5 steps to reach such objective:\r
+  1. Sends out the ATAPI Identify Command to the specified device. \r
+  Only ATAPI device responses to this command. If the command succeeds,\r
+  it returns the Identify data structure which filled with information \r
+  about the device. Since the ATAPI device contains removable media, \r
+  the only meaningful information is the device module name.\r
+  2. Sends out ATAPI Inquiry Packet Command to the specified device.\r
+  This command will return inquiry data of the device, which contains\r
+  the device type information.\r
+  3. Allocate sense data space for future use. We don't detect the media\r
+  presence here to improvement boot performance, especially when CD \r
+  media is present. The media detection will be performed just before\r
+  each BLK_IO read/write\r
+  \r
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                 to record all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS       Identify ATAPI device successfully.\r
+  @retval EFI_DEVICE_ERROR  ATAPI Identify Device Command failed or device type\r
+                            is not supported by this IDE driver.\r
+  @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed \r
 \r
+  @note   Parameter "IdeDev" will be updated in this function.\r
 **/\r
 EFI_STATUS\r
 ATAPIIdentify (\r
@@ -560,185 +620,22 @@ ATAPIIdentify (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is used to implement the Soft Reset on the specified\r
+  ATAPI device. Different from the AtaSoftReset(), here reset is a ATA\r
+  Soft Reset Command special for ATAPI device, and it only take effects\r
+  on the specified ATAPI device, not on the whole IDE bus.\r
+  Since the ATAPI soft reset is needed when device is in exceptional\r
+  condition (such as BSY bit is always set ), I think the Soft Reset\r
+  command should be sent without waiting for the BSY clear and DRDY\r
+  set.\r
+  This function is called by IdeBlkIoReset(), \r
+  a interface function of Block I/O protocol.\r
 \r
-  @param  IdeDev TODO: add argument description\r
+  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
 \r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiInquiry (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Packet TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  TimeOut TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandIn (\r
-  IN  IDE_BLK_IO_DEV        *IdeDev,\r
-  IN  ATAPI_PACKET_COMMAND  *Packet,\r
-  IN  UINT16                *Buffer,\r
-  IN  UINT32                ByteCount,\r
-  IN  UINTN                 TimeOut\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Packet TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  TimeOut TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiPacketCommandOut (\r
-  IN  IDE_BLK_IO_DEV        *IdeDev,\r
-  IN  ATAPI_PACKET_COMMAND  *Packet,\r
-  IN  UINT16                *Buffer,\r
-  IN  UINT32                ByteCount,\r
-  IN  UINTN                 TimeOut\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  Read TODO: add argument description\r
-  @param  TimeOut TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-PioReadWriteData (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT16          *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  BOOLEAN         Read,\r
-  IN  UINTN           TimeOut\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev  TODO: add argument description\r
-  @param  SResult TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiTestUnitReady (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  OUT SENSE_RESULT       *SResult  \r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  SenseCounts TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiRequestSense (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  OUT UINTN           *SenseCounts\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev  TODO: add argument description\r
-  @param  SResult TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadCapacity (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  OUT SENSE_RESULT       *SResult  \r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  MediaChange TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiDetectMedia (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  OUT BOOLEAN         *MediaChange\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadSectors (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *Buffer,\r
-  IN  EFI_LBA         Lba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiWriteSectors (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *Buffer,\r
-  IN  EFI_LBA         Lba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS      Soft reset completes successfully.\r
+  @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -747,16 +644,26 @@ AtapiSoftReset (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeBlkIoDevice TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  This function is the ATAPI implementation for ReadBlocks in the\r
+  Block I/O Protocol interface.\r
 \r
+  @param IdeBlkIoDevice Indicates the calling context.\r
+  @param MediaId        The media id that the read request is for.\r
+  @param LBA            The starting logical block address to read from on the device.\r
+  @param BufferSize     The size of the Buffer in bytes. This must be a multiple\r
+                        of the intrinsic block size of the device.\r
+  @param Buffer         A pointer to the destination buffer for the data. The caller\r
+                        is responsible for either having implicit or explicit \r
+                        ownership of the memory that data is read into.\r
+  \r
+  @retval EFI_SUCCESS           Read Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR      Read Blocks failed.\r
+  @retval EFI_NO_MEDIA          There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
+                                or the data buffer is not valid.\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoReadBlocks (\r
@@ -768,16 +675,28 @@ AtapiBlkIoReadBlocks (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  This function is the ATAPI implementation for WriteBlocks in the\r
+  Block I/O Protocol interface.\r
 \r
-  @param  IdeBlkIoDevice TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
+  @param IdeBlkIoDevice  Indicates the calling context.\r
+  @param MediaId         The media id that the write request is for.\r
+  @param LBA             The starting logical block address to write onto the device.\r
+  @param BufferSize      The size of the Buffer in bytes. This must be a multiple\r
+                         of the intrinsic block size of the device.\r
+  @param Buffer          A pointer to the source buffer for the data. The caller\r
+                         is responsible for either having implicit or explicit ownership\r
+                         of the memory that data is written from.\r
 \r
-  TODO: add return values.\r
+  @retval EFI_SUCCESS            Write Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR       Write Blocks failed.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE       The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the\r
+                                 intrinsic block size of the device.  \r
+  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid, \r
+                                 or the data buffer is not valid.\r
 \r
+  @retval EFI_WRITE_PROTECTED    The write protected is enabled or the media does not support write\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoWriteBlocks (\r
@@ -789,56 +708,9 @@ AtapiBlkIoWriteBlocks (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  SenseCount TODO: add argument description\r
-  @param  Result TODO: add argument description\r
+  Release resources of an IDE device before stopping it.\r
 \r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-ParseSenseData (\r
-  IN IDE_BLK_IO_DEV     *IdeDev,\r
-  IN UINTN              SenseCount,\r
-  OUT SENSE_RESULT      *Result\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtapiReadPendingData (\r
-  IN IDE_BLK_IO_DEV     *IdeDev\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  WriteProtected TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-IsLS120orZipWriteProtected (\r
-  IN  IDE_BLK_IO_DEV    *IdeDev,\r
-  OUT BOOLEAN           *WriteProtected\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeBlkIoDevice TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param IdeBlkIoDevice  Standard IDE device private data structure\r
 \r
 **/\r
 VOID\r
@@ -847,49 +719,32 @@ ReleaseIdeResources (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  TransferMode TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  Set the calculated Best transfer mode to a detected device\r
 \r
+  @param IdeDev       Standard IDE device private data structure\r
+  @param TransferMode The device transfer mode to be set\r
+  @return Set transfer mode Command execute status.\r
 **/\r
 EFI_STATUS\r
 SetDeviceTransferMode (\r
   IN IDE_BLK_IO_DEV       *IdeDev,\r
   IN ATA_TRANSFER_MODE    *TransferMode\r
   );\r
-\r
 /**\r
-  TODO: Add function description\r
+  Send ATA command into device with NON_DATA protocol\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  NativeMaxAddress TODO: add argument description\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaLow The value in LBA_LOW register\r
+  @param  LbaMiddle The value in LBA_MIDDLE register\r
+  @param  LbaHigh The value in LBA_HIGH register\r
 \r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-ReadNativeMaxAddress (\r
-  IN  IDE_BLK_IO_DEV                *IdeDev,\r
-  OUT EFI_LBA                       *NativeMaxAddress\r
-  );\r
-\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Device TODO: add argument description\r
-  @param  Feature TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  LbaLow TODO: add argument description\r
-  @param  LbaMiddle TODO: add argument description\r
-  @param  LbaHigh TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_ABORTED Command failed\r
+  @retval  EFI_DEVICE_ERROR Device status error.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -905,16 +760,18 @@ AtaNonDataCommandIn (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Send ATA Ext command into device with NON_DATA protocol\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Device TODO: add argument description\r
-  @param  Feature TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  LbaAddress TODO: add argument description\r
+  @param  IdeDev Standard IDE device private data structure\r
+  @param  AtaCommand The ATA command to be sent\r
+  @param  Device The value in Device register\r
+  @param  Feature The value in Feature register\r
+  @param  SectorCount The value in SectorCount register\r
+  @param  LbaAddress The LBA address in 48-bit mode\r
 \r
-  TODO: add return values.\r
+  @retval  EFI_SUCCESS Reading succeed\r
+  @retval  EFI_ABORTED Command failed\r
+  @retval  EFI_DEVICE_ERROR Device status error.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -926,230 +783,6 @@ AtaNonDataCommandInExt (
   IN  UINT16          SectorCount,\r
   IN  EFI_LBA         LbaAddress\r
   );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaReadSectorsExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaWriteSectorsExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaReadExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaRead (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWriteExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).\r
-  \r
-  @param[in] *IdeDev\r
-  pointer pointing to IDE_BLK_IO_DEV data structure, used\r
-  to record all the information of the IDE device.\r
-\r
-  @param[in] *DataBuffer\r
-  A pointer to the source buffer for the data.\r
-\r
-  @param[in] StartLba\r
-  The starting logical block address to write to\r
-  on the device media.\r
-\r
-  @param[in] NumberOfBlocks\r
-  The number of transfer data blocks.\r
-  \r
-  @param[in] UdmaOp\r
-  The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,\r
-  AtaUdmaWriteOp, AtaUdmaWriteExOp\r
-\r
-  @return The device status of UDMA operation. If the operation is\r
-  successful, return EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-DoAtaUdma (\r
-  IN  IDE_BLK_IO_DEV      *IdeDev,\r
-  IN  VOID                *DataBuffer,\r
-  IN  EFI_LBA             StartLba,\r
-  IN  UINTN               NumberOfBlocks,\r
-  IN  ATA_UDMA_OPERATION  UdmaOp\r
-  );\r
-\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DataBuffer TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  NumberOfBlocks TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaUdmaWrite (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *DataBuffer,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINTN           NumberOfBlocks\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Device TODO: add argument description\r
-  @param  Feature TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  LbaAddress TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssueExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT16          Feature,\r
-  IN  UINT16          SectorCount,\r
-  IN  EFI_LBA         LbaAddress\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  Device TODO: add argument description\r
-  @param  Feature TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-  @param  LbaAddress TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaCommandIssue (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  UINT8           AtaCommand,\r
-  IN  UINT8           Device,\r
-  IN  UINT16          Feature,\r
-  IN  UINT16          SectorCount,\r
-  IN  EFI_LBA         LbaAddress\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaAtapi6Identify (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  );\r
-\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-VOID\r
-AtaSMARTSupport (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\r
-  );\r
-\r
-\r
 /**\r
   Enable Long Physical Sector Feature for ATA device.\r
 \r
@@ -1166,58 +799,11 @@ AtaEnableLongPhysicalSector (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Set drive parameters for devices not support PACKETS command\r
 \r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataInExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  OUT VOID        *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  UINT8           AtaCommand,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINT16          SectorCount\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  Buffer TODO: add argument description\r
-  @param  ByteCount TODO: add argument description\r
-  @param  AtaCommand TODO: add argument description\r
-  @param  StartLba TODO: add argument description\r
-  @param  SectorCount TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-AtaPioDataOutExt (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev,\r
-  IN  VOID            *Buffer,\r
-  IN  UINT32          ByteCount,\r
-  IN  UINT8           AtaCommand,\r
-  IN  EFI_LBA         StartLba,\r
-  IN  UINT16          SectorCount\r
-  );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
-  @param  DriveParameters TODO: add argument description\r
-\r
-  TODO: add return values.\r
+  @param IdeDev          Standard IDE device private data structure\r
+  @param DriveParameters The device parameters to be set into the disk\r
+  @return SetParameters Command execute status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1227,30 +813,14 @@ SetDriveParameters (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  IdeDev TODO: add argument description\r
+  Enable Interrupt on IDE controller\r
 \r
-  TODO: add return values.\r
+  @param  IdeDev   Standard IDE device private data structure\r
 \r
+  @retval  EFI_SUCCESS Enable Interrupt successfully\r
 **/\r
 EFI_STATUS\r
 EnableInterrupt (\r
   IN IDE_BLK_IO_DEV       *IdeDev\r
   );\r
-\r
-/**\r
-  Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
-\r
-  @param[in]  Event   Pointer to this event.\r
-  @param[in]  Context Event hanlder private data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ClearInterrupt (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  );\r
-\r
 #endif\r
index 9c7d6e20637fb7bb9e986e8c8538e95dd14c4e64..b3434d754e89b5d841833059a1883ebd6be41e85 100644 (file)
@@ -1,4 +1,8 @@
 /** @file\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 - 2008, Intel Corporation\r
   All rights reserved. This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -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,8 +143,6 @@ 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
@@ -134,22 +221,18 @@ IDEBusDriverBindingSupported (
   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
@@ -698,7 +781,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
@@ -821,14 +904,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
@@ -847,8 +925,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
@@ -949,115 +1025,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
-\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
-  if (Index < MAX_IDE_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
-  GC_TODO: Add function description\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
-  @param  This                  GC_TODO: add argument description.\r
-  @param  ExtendedVerification  GC_TODO: add argument description.\r
-\r
-  @retval EFI_DEVICE_ERROR      GC_TODO: Add description for return value.\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
@@ -1107,15 +1083,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
@@ -1127,7 +1104,6 @@ IDEBlkIoReadBlocks (
   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
@@ -1182,13 +1158,14 @@ Done:
 /**\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
@@ -1200,7 +1177,6 @@ IDEBlkIoWriteBlocks (
   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
@@ -1250,19 +1226,13 @@ Done:
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
-\r
-//\r
-// ***********************************************************************************\r
-// IDEBlkIoFlushBlocks\r
-// ***********************************************************************************\r
-//\r
 /**\r
-  TODO: Add function description\r
+  Flushes all modified data to a physical block devices\r
 \r
-  @param  This TODO: add argument description\r
-\r
-  @retval EFI_SUCCESS   GC_TODO: Add description for return value.\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
@@ -1362,14 +1332,14 @@ IDEDiskInfoIdentify (
   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  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_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
@@ -1389,11 +1359,11 @@ IDEDiskInfoSenseData (
   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  This       Protocol instance pointer.\r
   @param  IdeChannel Primary or Secondary\r
-  @param  IdeDevice Master or Slave\r
+  @param  IdeDevice  Master or Slave\r
 \r
-  @retval  EFI_SUCCESS IdeChannel and IdeDevice are valid\r
+  @retval  EFI_SUCCESS     IdeChannel and IdeDevice are valid\r
   @retval  EFI_UNSUPPORTED This is not an IDE device\r
 \r
 **/\r
@@ -1414,6 +1384,103 @@ 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 hanlder 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
+  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
index 092b219503c5a273cf86afc3ba8d053e5f5a76d4..55f4b72f16856e85ef748e95489d06d7ffabe191 100644 (file)
@@ -119,34 +119,16 @@ typedef struct {
 \r
 #include "Ide.h"\r
 \r
-//\r
-// Prototypes\r
-// Driver model protocol interface\r
-//\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  ImageHandle TODO: add argument description\r
-  @param  SystemTable TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IDEBusControllerDriverEntryPoint (\r
-  IN EFI_HANDLE                   ImageHandle,\r
-  IN EFI_SYSTEM_TABLE             *SystemTable\r
-  );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Supported function of Driver Binding protocol for this driver.\r
 \r
-  @param  This TODO: add argument description\r
-  @param  Controller TODO: add argument description\r
-  @param  RemainingDevicePath TODO: add argument description\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
-  TODO: add return values.\r
+  @retval  EFI_SUCCESS Driver loaded.\r
+  @retval  other       Driver not loaded.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -158,13 +140,16 @@ IDEBusDriverBindingSupported (
   );\r
 \r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  Controller TODO: add argument description\r
-  @param  RemainingDevicePath TODO: add argument description\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
-  TODO: add return values.\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
@@ -176,14 +161,16 @@ IDEBusDriverBindingStart (
   );\r
 \r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  Controller TODO: add argument description\r
-  @param  NumberOfChildren TODO: add argument description\r
-  @param  ChildHandleBuffer TODO: add argument description\r
+  @param  This Protocol instance pointer.\r
+  @param  Controller Handle of device to stop driver on\r
+  @param  NumberOfChildren Not used\r
+  @param  ChildHandleBuffer Not used\r
 \r
-  TODO: add return values.\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
@@ -199,16 +186,38 @@ IDEBusDriverBindingStop (
 // EFI Driver Configuration Functions\r
 //\r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  This                 TODO: add argument description\r
-  @param  ControllerHandle     TODO: add argument description\r
-  @param  ChildHandle          TODO: add argument description\r
-  @param  Language             TODO: add argument description\r
-  @param  ActionRequired       TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
+  Allows the user to set controller specific options for a controller that a \r
+  driver is currently managing.\r
+\r
+  @param  This              A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+  @param  ControllerHandle  The handle of the controller to set options on.\r
+  @param  ChildHandle       The handle of the child controller to set options on.\r
+                            This is an optional parameter that may be NULL.\r
+                            It will be NULL for device drivers, and for a bus drivers\r
+                            that wish to set options for the bus controller.\r
+                            It will not be NULL for a bus driver that wishes to set\r
+                            options for one of its child controllers.\r
+  @param  Language          A pointer to a three character ISO 639-2 language identifier. \r
+                            This is the language of the user interface that should be presented \r
+                            to the user, and it must match one of the languages specified in \r
+                            SupportedLanguages. The number of languages supported by a driver is up to\r
+                            the driver writer.\r
+  @param  ActionRequired    A pointer to the action that the calling agent is required \r
+                            to perform when this function returns.\r
+  \r
+\r
+  @retval  EFI_SUCCESS           The driver specified by This successfully set the configuration \r
+                                 options for the controller specified by ControllerHandle..\r
+  @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support setting configuration options for \r
+                                 the controller specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the language specified by Language.\r
+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempt to set the configuration options for the \r
+                                 controller specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_OUT_RESOURCES     There are not enough resources available to set the configuration options for the \r
+                                 controller specified by ControllerHandle and ChildHandle\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -221,14 +230,27 @@ IDEBusDriverConfigurationSetOptions (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  This                 TODO: add argument description\r
-  @param  ControllerHandle     TODO: add argument description\r
-  @param  ChildHandle          TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
+  Tests to see if a controller's current configuration options are valid.\r
+\r
+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.\r
+  @param  ControllerHandle The handle of the controller to test if it's current configuration options \r
+                           are valid.\r
+  @param  ChildHandle      The handle of the child controller to test if it's current configuration \r
+                           options are valid.  This is an optional parameter that may be NULL. It will \r
+                           be NULL for device drivers.  It will also be NULL for a bus drivers that\r
+                           wish to test the configuration options for the bus controller. It will \r
+                           not be NULL for a bus driver that wishes to test configuration options for \r
+                           one of its child controllers.\r
+  @retval  EFI_SUCCESS           The controller specified by ControllerHandle and ChildHandle that is being\r
+                                 managed by the driver specified by This has a valid set of  configuration\r
+                                 options.\r
+  @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This is not currently  managing the controller \r
+                                 specified by ControllerHandle and ChildHandle.\r
+  @retval  EFI_DEVICE_ERROR      The controller specified by ControllerHandle and ChildHandle that is being\r
+                                 managed by the driver specified by This has an invalid set of configuration\r
+                                 options.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -239,16 +261,36 @@ IDEBusDriverConfigurationOptionsValid (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  This                 TODO: add argument description\r
-  @param  ControllerHandle     TODO: add argument description\r
-  @param  ChildHandle          TODO: add argument description\r
-  @param  DefaultType          TODO: add argument description\r
-  @param  ActionRequired       TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
+  Forces a driver to set the default configuration options for a controller.\r
+\r
+  @param  This             A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.\r
+  @param  ControllerHandle The handle of the controller to force default configuration options on.\r
+  @param  ChildHandle      The handle of the child controller to force default configuration \r
+                           options on  This is an optional parameter that may be NULL.  It \r
+                           will be NULL for device drivers. It will also be NULL for a bus \r
+                           drivers that wish to force default configuration options for the bus\r
+                           controller.  It will not be NULL for a bus driver that wishes to force\r
+                           default configuration options for one of its child controllers.\r
+  @param  DefaultType      The type of default configuration options to force on the controller \r
+                           specified by ControllerHandle and ChildHandle. \r
+  @param  ActionRequired   A pointer to the action that the calling agent is required to perform \r
+                           when this function returns.\r
+\r
+  @retval  EFI_SUCCESS           The driver specified by This successfully forced the \r
+                                 default configuration options on the controller specified by \r
+                                 ControllerHandle and ChildHandle.\r
+  @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ActionRequired is NULL.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support forcing the default \r
+                                 configuration options on the controller specified by ControllerHandle\r
+                                 and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the configuration type \r
+                                 specified by DefaultType.\r
+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempt to force the default configuration \r
+                                 options on the controller specified by  ControllerHandle and ChildHandle.\r
+  @retval  EFI_OUT_RESOURCES     There are not enough resources available to force the default configuration \r
+                                 options on the controller specified by ControllerHandle and ChildHandle.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -264,19 +306,51 @@ IDEBusDriverConfigurationForceDefaults (
 // EFI Driver Diagnostics Functions\r
 //\r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  This                 TODO: add argument description\r
-  @param  ControllerHandle     TODO: add argument description\r
-  @param  ChildHandle          TODO: add argument description\r
-  @param  DiagnosticType       TODO: add argument description\r
-  @param  Language             TODO: add argument description\r
-  @param  ErrorType            TODO: add argument description\r
-  @param  BufferSize           TODO: add argument description\r
-  @param  Buffer               TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
+  Runs diagnostics on a controller.\r
+\r
+  @param  This             A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOLinstance.\r
+  @param  ControllerHandle The handle of the controller to run diagnostics on.\r
+  @param  ChildHandle      The handle of the child controller to run diagnostics on\r
+                           This is an optional parameter that may be NULL.  It will\r
+                           be NULL for device drivers.  It will also be NULL for a\r
+                           bus drivers that wish to run diagnostics on the bus controller. \r
+                           It will not be NULL for a bus driver that wishes to run \r
+                           diagnostics on one of its child controllers.\r
+  @param  DiagnosticType   Indicates type of diagnostics to perform on the controller\r
+                           specified by ControllerHandle and ChildHandle.\r
+  @param  Language         A pointer to a three character ISO 639-2 language identifier. \r
+                           This is the language in which the optional error message should \r
+                           be returned in Buffer, and it must match one of the languages \r
+                           specified in SupportedLanguages. The number of languages supported by\r
+                           a driver is up to the driver writer.\r
+  @param  ErrorType        A GUID that defines the format of the data returned in Buffer.\r
+  @param  BufferSize       The size, in bytes, of the data returned in Buffer.\r
+  @param  Buffer           A buffer that contains a Null-terminated Unicode string\r
+                           plus some additional data whose format is defined by ErrorType.  \r
+                           Buffer is allocated by this function with AllocatePool(), and \r
+                           it is the caller's responsibility to free it with a call to FreePool().\r
+\r
+  @retval  EFI_SUCCESS           The controller specified by ControllerHandle and ChildHandle passed \r
+                                 the diagnostic.\r
+  @retval  EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+  @retval  EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval  EFI_INVALID_PARAMETER ErrorType is NULL.\r
+  @retval  EFI_INVALID_PARAMETER BufferType is NULL.\r
+  @retval  EFI_INVALID_PARAMETER Buffer is NULL.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support running \r
+                                 diagnostics for the controller specified by ControllerHandle \r
+                                 and ChildHandle.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the\r
+                                 type of diagnostic specified by DiagnosticType.\r
+  @retval  EFI_UNSUPPORTED       The driver specified by This does not support the language \r
+                                 specified by Language.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to complete the \r
+                                 diagnostics.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to return the \r
+                                 status information in ErrorType, BufferSize,and Buffer.\r
+  @retval  EFI_DEVICE_ERROR      The controller specified by ControllerHandle and ChildHandle \r
+                                 did not pass the diagnostic.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -291,16 +365,15 @@ IDEBusDriverDiagnosticsRunDiagnostics (
   OUT CHAR16                                        **Buffer\r
   );\r
 \r
-//\r
-// Block I/O Protocol Interface\r
-//\r
 /**\r
-  TODO: Add function description\r
-\r
-  @param  This TODO: add argument description\r
-  @param  ExtendedVerification TODO: add argument description\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
-  TODO: add return values.\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
@@ -311,15 +384,16 @@ IDEBlkIoReset (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Read data from a block IO device\r
 \r
-  @param  This TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\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
 \r
-  TODO: add return values.\r
+  @retval EFI_DEVICE_ERROR  unknown device type\r
+  @retval EFI_SUCCESS       read the data successfully.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -333,15 +407,16 @@ IDEBlkIoReadBlocks (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Write data to block io device\r
 \r
-  @param  This TODO: add argument description\r
-  @param  MediaId TODO: add argument description\r
-  @param  Lba TODO: add argument description\r
-  @param  BufferSize TODO: add argument description\r
-  @param  Buffer TODO: add argument description\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
-  TODO: add return values.\r
+  @retval EFI_DEVICE_ERROR  unknown device type\r
+  @retval other             write data status\r
 \r
 **/\r
 EFI_STATUS\r
@@ -355,42 +430,30 @@ IDEBlkIoWriteBlocks (
   );\r
 \r
 /**\r
-  TODO: Add function description\r
+  Flushes all modified data to a physical block devices\r
 \r
-  @param  This TODO: add argument description\r
-\r
-  TODO: add return values.\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
 IDEBlkIoFlushBlocks (\r
   IN  EFI_BLOCK_IO_PROTOCOL       *This\r
   );\r
-\r
-/**\r
-  TODO: Add function description\r
-\r
-  @param  PciIo TODO: add argument description\r
-  @param  Enable TODO: add argument description\r
-\r
-  TODO: add return values.\r
-\r
-**/\r
-EFI_STATUS\r
-IDERegisterDecodeEnableorDisable (\r
-  IN  EFI_PCI_IO_PROTOCOL         *PciIo,\r
-  IN  BOOLEAN                     Enable\r
-  );\r
-\r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  InquiryData TODO: add argument description\r
-  @param  IntquiryDataSize TODO: add argument description\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
-  TODO: add return values.\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
@@ -402,13 +465,17 @@ IDEDiskInfoInquiry (
   );\r
 \r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  IdentifyData TODO: add argument description\r
-  @param  IdentifyDataSize TODO: add argument description\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
-  TODO: add return values.\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
@@ -420,14 +487,18 @@ IDEDiskInfoIdentify (
   );\r
 \r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  SenseData TODO: add argument description\r
-  @param  SenseDataSize TODO: add argument description\r
-  @param  SenseDataNumber TODO: add argument description\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
-  TODO: add return values.\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
@@ -440,13 +511,15 @@ IDEDiskInfoSenseData (
   );\r
 \r
 /**\r
-  TODO: Add function description\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 TODO: add argument description\r
-  @param  IdeChannel TODO: add argument description\r
-  @param  IdeDevice TODO: add argument description\r
+  @param  This       Protocol instance pointer.\r
+  @param  IdeChannel Primary or Secondary\r
+  @param  IdeDevice  Master or Slave\r
 \r
-  TODO: add return values.\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
@@ -456,5 +529,18 @@ IDEDiskInfoWhichIde (
   OUT UINT32                      *IdeChannel,\r
   OUT UINT32                      *IdeDevice\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 hanlder private data\r
 \r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  );\r
 #endif\r