]> git.proxmox.com Git - mirror_edk2.git/commitdiff
fixed the following problems:
authoreric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 12 Oct 2007 05:41:48 +0000 (05:41 +0000)
committereric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 12 Oct 2007 05:41:48 +0000 (05:41 +0000)
1) DMA interrupt don't been cleaning up after one UDMA operation
2) Global variable mHobStart is not updated after invoking CoreInitializeGcdServices() func in the dxemain.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4107 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/ata.c
MdeModulePkg/Core/Dxe/DxeMain.h
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
MdeModulePkg/Core/Dxe/Gcd/gcd.c

index ec546bb6b24b41121e56297db0907aa815bffefa..3a7271ec4723b855ad0b40f988d20fad2b49c7e6 100644 (file)
@@ -56,6 +56,7 @@ ATAIdentify (
   EFI_IDENTIFY_DATA *AtaIdentifyPointer;\r
   UINT32            Capacity;\r
   UINT8             DeviceSelect;\r
+  UINTN                                Retry;\r
 \r
   //\r
   //  AtaIdentifyPointer is used for accommodating returned IDENTIFY data of\r
@@ -68,81 +69,101 @@ ATAIdentify (
   //  and receive data from device\r
   //\r
   DeviceSelect  = (UINT8) ((IdeDev->Device) << 4);\r
-  Status = AtaPioDataIn (\r
-            IdeDev,\r
-            (VOID *) AtaIdentifyPointer,\r
-            sizeof (EFI_IDENTIFY_DATA),\r
-            ATA_CMD_IDENTIFY_DRIVE,\r
-            DeviceSelect,\r
-            0,\r
-            0,\r
-            0,\r
-            0\r
-            );\r
-  //\r
-  // If ATA Identify command succeeds, then according to the received\r
-  // IDENTIFY data,\r
-  // identify the device type ( ATA or not ).\r
-  // If ATA device, fill the information in IdeDev.\r
-  // If not ATA device, return IDE_DEVICE_ERROR\r
-  //\r
-  if (!EFI_ERROR (Status)) {\r
-\r
-    IdeDev->pIdData = AtaIdentifyPointer;\r
 \r
+  \r
+  Retry = 3;\r
+  while (Retry > 0) {  \r
+    Status = AtaPioDataIn (\r
+              IdeDev,\r
+              (VOID *) AtaIdentifyPointer,\r
+              sizeof (EFI_IDENTIFY_DATA),\r
+              ATA_CMD_IDENTIFY_DRIVE,\r
+              DeviceSelect,\r
+              0,\r
+              0,\r
+              0,\r
+              0\r
+              );\r
     //\r
-    // Print ATA Module Name\r
+    // If ATA Identify command succeeds, then according to the received\r
+    // IDENTIFY data,\r
+    // identify the device type ( ATA or not ).\r
+    // If ATA device, fill the information in IdeDev.\r
+    // If not ATA device, return IDE_DEVICE_ERROR\r
     //\r
-    PrintAtaModuleName (IdeDev);\r
+    if (!EFI_ERROR (Status)) {\r
+\r
+      IdeDev->pIdData = AtaIdentifyPointer;\r
 \r
-    //\r
-    // bit 15 of pAtaIdentify->config is used to identify whether device is\r
-    // ATA device or ATAPI device.\r
-    // if 0, means ATA device; if 1, means ATAPI device.\r
-    //\r
-    if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {\r
       //\r
-      // Detect if support S.M.A.R.T. If yes, enable it as default\r
+      // Print ATA Module Name\r
       //\r
-      AtaSMARTSupport (IdeDev);\r
+      PrintAtaModuleName (IdeDev);\r
 \r
       //\r
-      // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)\r
+      // bit 15 of pAtaIdentify->config is used to identify whether device is\r
+      // ATA device or ATAPI device.\r
+      // if 0, means ATA device; if 1, means ATAPI device.\r
       //\r
-      Status = AtaAtapi6Identify (IdeDev);\r
-      if (!EFI_ERROR (Status)) {\r
+      if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {\r
         //\r
-        // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()\r
+        // Detect if support S.M.A.R.T. If yes, enable it as default\r
         //\r
-        return EFI_SUCCESS;\r
-      }\r
-      //\r
-      // This is a hard disk <= 120GB capacity, treat it as normal hard disk\r
-      //\r
-      IdeDev->Type = IdeHardDisk;\r
+        AtaSMARTSupport (IdeDev);\r
 \r
-      //\r
-      // Block Media Information:\r
-      // Media->LogicalPartition , Media->WriteCaching will be filled\r
-      // in 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
+        //\r
+        // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)\r
+        //\r
+        Status = AtaAtapi6Identify (IdeDev);\r
+        if (!EFI_ERROR (Status)) {\r
+          //\r
+          // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()\r
+          //\r
+          return EFI_SUCCESS;\r
+        } else if (Status == EFI_DEVICE_ERROR) {\r
+                 //\r
+                 // Some disk with big capacity (>200GB) is slow when being identified\r
+                 // and will return all zero for word83.\r
+                 // We try twice at first. If it fails, we do a SoftRest and try again.\r
+                 //\r
+                 Retry--;\r
+                 if (Retry == 1) {\r
+                   //\r
+                   // Do a SoftRest before the third attempt.\r
+                   //\r
+                   AtaSoftReset (IdeDev);\r
+                 }\r
+                 continue;\r
+           }\r
+        //\r
+        // This is a hard disk <= 120GB capacity, treat it as normal hard disk\r
+        //\r
+        IdeDev->Type = IdeHardDisk;\r
 \r
-      //\r
-      // Calculate device capacity\r
-      //\r
-      Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |\r
+        //\r
+        // Block Media Information:\r
+        // Media->LogicalPartition , Media->WriteCaching will be filled\r
+        // in 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
+\r
+        //\r
+        // Calculate device capacity\r
+        //\r
+        Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |\r
                   AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;\r
-      IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
+        IdeDev->BlkIo.Media->LastBlock = Capacity - 1;\r
 \r
-      return EFI_SUCCESS;\r
+        return EFI_SUCCESS;\r
+      }\r
 \r
     }\r
+       break;\r
   }\r
 \r
   gBS->FreePool (AtaIdentifyPointer);\r
@@ -167,8 +188,9 @@ ATAIdentify (
   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\r
-  needed\r
+  the capacity is below 120G, 48bit addressing is not needed\r
+\r
+  @retval  EFI_DEVICE_ERROR The identify data in IdeDev is incorrect\r
 \r
   @note\r
   This function must be called after DEVICE_IDENTITY command has been\r
@@ -191,6 +213,13 @@ AtaAtapi6Identify (
 \r
   Atapi6IdentifyStruct = IdeDev->pIdData;\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
@@ -2298,18 +2327,17 @@ DoAtaUdma (
   }\r
 \r
   //\r
-  // Channel and device differential\r
+  // Select device\r
   //\r
   Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);\r
+  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
 \r
   //\r
-  // Enable interrupt to support UDMA and Select device\r
+  // Enable interrupt to support UDMA\r
   //\r
   DeviceControl = 0;\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
 \r
-  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);\r
-\r
   if (IdePrimary == IdeDev->Channel) {\r
     IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;\r
     IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
@@ -2324,6 +2352,31 @@ DoAtaUdma (
     }\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
+  Status = EFI_SUCCESS;\r
+  \r
   RemainBlockNum = NumberOfBlocks;\r
   while (RemainBlockNum > 0) {\r
 \r
@@ -2452,29 +2505,6 @@ DoAtaUdma (
                         &RegisterValue\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
     if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {\r
       Status = AtaCommandIssueExt (\r
                  IdeDev,\r
@@ -2530,6 +2560,7 @@ DoAtaUdma (
     // 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
@@ -2543,31 +2574,8 @@ DoAtaUdma (
                           );\r
       if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
         if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
-          //\r
-          // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\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
-          RegisterValue &= ~((UINT8)BMIC_START);\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
-          IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
-          IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
-          return EFI_DEVICE_ERROR;\r
+                 Status = EFI_DEVICE_ERROR;\r
+                 break;\r
         }\r
         break;\r
       }\r
@@ -2579,6 +2587,28 @@ DoAtaUdma (
     IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
     IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\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
     // Read Status Register of IDE device to clear interrupt\r
     //\r
     RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
@@ -2609,6 +2639,9 @@ DoAtaUdma (
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
+       if (EFI_ERROR (Status)) {\r
+         break;\r
+       }\r
     DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;\r
     StartLba += NumberOfBlocks;\r
   }\r
@@ -2620,5 +2653,6 @@ DoAtaUdma (
   DeviceControl |= ATA_CTLREG_IEN_L;\r
   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
+\r
index 26fb9190e3e0bd7392ee7d63800acc5e4d3bc4ba..b4da26a63d962157f31b6ca623ac4b821c9de0d9 100644 (file)
@@ -354,7 +354,7 @@ Returns:
 \r
 EFI_STATUS\r
 CoreInitializeGcdServices (\r
-  IN VOID                  **HobStart,\r
+  IN OUT VOID                  **HobStart,\r
   IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,\r
   IN UINT64                MemoryLength\r
   )\r
@@ -367,7 +367,8 @@ Routine Description:
   memory map, so memory allocations and resource allocations can be made.  The first\r
   part of this function can not depend on any memory services until at least one\r
   memory descriptor is provided to the memory services.  Then the memory services\r
-  can be used to intialize the GCD map.\r
+  can be used to intialize the GCD map. The HobStart will be relocated to a pool\r
+  buffer.\r
 \r
 Arguments:\r
 \r
index 53f1d5f594c0c2a4f58175eb56d802a8af1ecdbe..59a5283a5facf436859dd2447cec5058d6117dd7 100644 (file)
@@ -299,6 +299,10 @@ Returns:
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
+  // The HobStart is relocated in gcd service init. Sync mHobStart varible.\r
+  //\r
+  mHobStart = HobStart;\r
+  \r
   // Install the DXE Services Table into the EFI System Tables's Configuration Table\r
   //\r
   Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);\r
@@ -867,4 +871,3 @@ DxeMainUefiDecompress (
 \r
   return UefiDecompress (Source, Destination, Scratch);\r
 }\r
-\r
index 4d58687c69230e9b365212fc8cd1473748852ae6..accc329a4ab7b839d77553d94e3303acf87e67d2 100644 (file)
@@ -2242,7 +2242,7 @@ Returns:
 \r
 EFI_STATUS\r
 CoreInitializeGcdServices (\r
-  IN VOID                  **HobStart,\r
+  IN OUT VOID                  **HobStart,\r
   IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,\r
   IN UINT64                MemoryLength\r
   )\r
@@ -2255,7 +2255,8 @@ Routine Description:
   memory map, so memory allocations and resource allocations can be made.  The first\r
   part of this function can not depend on any memory services until at least one\r
   memory descriptor is provided to the memory services.  Then the memory services\r
-  can be used to intialize the GCD map.\r
+  can be used to intialize the GCD map. The HobStart will be relocated to a pool \r
+  buffer.\r
 \r
 Arguments:\r
 \r