]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
MdeModulePkg/PciBus: Add IOMMU support.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdMmcPciHcDxe.c
index 59649e1cad4d4864d625bc43df2de01bd2309c5a..23faec5e2be0bbc9a317130822eecb0388f4fd4f 100644 (file)
@@ -51,8 +51,8 @@ SD_MMC_HC_PRIVATE_DATA gSdMmcPciHcTemplate = {
                                     // Queue\r
   INITIALIZE_LIST_HEAD_VARIABLE (gSdMmcPciHcTemplate.Queue),\r
   {                                 // Slot\r
-    {0, UnknownSlot, 0, 0}, {0, UnknownSlot, 0, 0}, {0, UnknownSlot, 0, 0},\r
-    {0, UnknownSlot, 0, 0}, {0, UnknownSlot, 0, 0}, {0, UnknownSlot, 0, 0}\r
+    {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0},\r
+    {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}\r
   },\r
   {                                 // Capability\r
     {0},\r
@@ -162,7 +162,7 @@ ProcessAsyncTaskList (
   Link   = GetFirstNode (&Private->Queue);\r
   if (!IsNull (&Private->Queue, Link)) {\r
     Trb = SD_MMC_HC_TRB_FROM_THIS (Link);\r
-    if (Private->Slot[Trb->Slot].MediaPresent == FALSE) {\r
+    if (!Private->Slot[Trb->Slot].MediaPresent) {\r
       Status = EFI_NO_MEDIA;\r
       goto Done;\r
     }\r
@@ -197,7 +197,7 @@ Done:
       Trb->Packet->TransactionStatus = EFI_TIMEOUT;\r
       TrbEvent = Trb->Event;\r
       SdMmcFreeTrb (Trb);\r
-      DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p EFI_TIMEOUT\n", TrbEvent));\r
+      DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p EFI_TIMEOUT\n", TrbEvent));\r
       gBS->SignalEvent (TrbEvent);\r
       return;\r
     }\r
@@ -207,7 +207,7 @@ Done:
     Trb->Packet->TransactionStatus = Status;\r
     TrbEvent = Trb->Event;\r
     SdMmcFreeTrb (Trb);\r
-    DEBUG ((EFI_D_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p with %r\n", TrbEvent, Status));\r
+    DEBUG ((DEBUG_VERBOSE, "ProcessAsyncTaskList(): Signal Event %p with %r\n", TrbEvent, Status));\r
     gBS->SignalEvent (TrbEvent);\r
   }\r
   return;\r
@@ -238,18 +238,21 @@ SdMmcPciHcEnumerateDevice (
   LIST_ENTRY                          *Link;\r
   LIST_ENTRY                          *NextLink;\r
   SD_MMC_HC_TRB                       *Trb;\r
+  EFI_TPL                             OldTpl;\r
 \r
   Private = (SD_MMC_HC_PRIVATE_DATA*)Context;\r
 \r
   for (Slot = 0; Slot < SD_MMC_HC_MAX_SLOT; Slot++) {\r
     if ((Private->Slot[Slot].Enable) && (Private->Slot[Slot].SlotType == RemovableSlot)) {\r
       Status = SdMmcHcCardDetect (Private->PciIo, Slot, &MediaPresent);\r
-      if ((Status == EFI_MEDIA_CHANGED) && (MediaPresent == FALSE)) {\r
-        DEBUG ((EFI_D_INFO, "SdMmcPciHcEnumerateDevice: device disconnected at slot %d of pci %p\n", Slot, Private->PciIo));\r
+      if ((Status == EFI_MEDIA_CHANGED) && !MediaPresent) {\r
+        DEBUG ((DEBUG_INFO, "SdMmcPciHcEnumerateDevice: device disconnected at slot %d of pci %p\n", Slot, Private->PciIo));\r
         Private->Slot[Slot].MediaPresent = FALSE;\r
+        Private->Slot[Slot].Initialized  = FALSE;\r
         //\r
         // Signal all async task events at the slot with EFI_NO_MEDIA status.\r
         //\r
+        OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
         for (Link = GetFirstNode (&Private->Queue);\r
              !IsNull (&Private->Queue, Link);\r
              Link = NextLink) {\r
@@ -262,6 +265,7 @@ SdMmcPciHcEnumerateDevice (
             SdMmcFreeTrb (Trb);\r
           }\r
         }\r
+        gBS->RestoreTPL (OldTpl);\r
         //\r
         // Notify the upper layer the connect state change through ReinstallProtocolInterface.\r
         //\r
@@ -272,8 +276,15 @@ SdMmcPciHcEnumerateDevice (
               &Private->PassThru\r
               );\r
       }\r
-      if ((Status == EFI_MEDIA_CHANGED) && (MediaPresent == TRUE)) {\r
-        DEBUG ((EFI_D_INFO, "SdMmcPciHcEnumerateDevice: device connected at slot %d of pci %p\n", Slot, Private->PciIo));\r
+      if ((Status == EFI_MEDIA_CHANGED) && MediaPresent) {\r
+        DEBUG ((DEBUG_INFO, "SdMmcPciHcEnumerateDevice: device connected at slot %d of pci %p\n", Slot, Private->PciIo));\r
+        //\r
+        // Reset the specified slot of the SD/MMC Pci Host Controller\r
+        //\r
+        Status = SdMmcHcReset (Private->PciIo, Slot);\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
         //\r
         // Reinitialize slot and restart identification process for the new attached device\r
         //\r
@@ -283,6 +294,7 @@ SdMmcPciHcEnumerateDevice (
         }\r
 \r
         Private->Slot[Slot].MediaPresent = TRUE;\r
+        Private->Slot[Slot].Initialized  = TRUE;\r
         RoutineNum = sizeof (mCardTypeDetectRoutineTable) / sizeof (CARD_TYPE_DETECT_ROUTINE);\r
         for (Index = 0; Index < RoutineNum; Index++) {\r
           Routine = &mCardTypeDetectRoutineTable[Index];\r
@@ -293,6 +305,12 @@ SdMmcPciHcEnumerateDevice (
             }\r
           }\r
         }\r
+        //\r
+        // This card doesn't get initialized correctly.\r
+        //\r
+        if (Index == RoutineNum) {\r
+          Private->Slot[Slot].Initialized = FALSE;\r
+        }\r
 \r
         //\r
         // Notify the upper layer the connect state change through ReinstallProtocolInterface.\r
@@ -509,8 +527,9 @@ SdMmcPciHcDriverBindingStart (
   CARD_TYPE_DETECT_ROUTINE        *Routine;\r
   UINT32                          RoutineNum;\r
   BOOLEAN                         MediaPresent;\r
+  BOOLEAN                         Support64BitDma;\r
 \r
-  DEBUG ((EFI_D_INFO, "SdMmcPciHcDriverBindingStart: Start\n"));\r
+  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStart: Start\n"));\r
 \r
   //\r
   // Open PCI I/O Protocol and save pointer to open protocol\r
@@ -582,6 +601,7 @@ SdMmcPciHcDriverBindingStart (
     goto Done;\r
   }\r
 \r
+  Support64BitDma = TRUE;\r
   for (Slot = FirstBar; Slot < (FirstBar + SlotNum); Slot++) {\r
     Private->Slot[Slot].Enable = TRUE;\r
 \r
@@ -591,6 +611,8 @@ SdMmcPciHcDriverBindingStart (
     }\r
     DumpCapabilityReg (Slot, &Private->Capability[Slot]);\r
 \r
+    Support64BitDma &= Private->Capability[Slot].SysBus64;\r
+\r
     Status = SdMmcHcGetMaxCurrent (PciIo, Slot, &Private->MaxCurrent[Slot]);\r
     if (EFI_ERROR (Status)) {\r
       continue;\r
@@ -598,7 +620,7 @@ SdMmcPciHcDriverBindingStart (
 \r
     Private->Slot[Slot].SlotType = Private->Capability[Slot].SlotType;\r
     if ((Private->Slot[Slot].SlotType != RemovableSlot) && (Private->Slot[Slot].SlotType != EmbeddedSlot)) {\r
-      DEBUG ((EFI_D_INFO, "SdMmcPciHcDxe doesn't support the slot type [%d]!!!\n", Private->Slot[Slot].SlotType));\r
+      DEBUG ((DEBUG_INFO, "SdMmcPciHcDxe doesn't support the slot type [%d]!!!\n", Private->Slot[Slot].SlotType));\r
       continue;\r
     }\r
 \r
@@ -615,8 +637,8 @@ SdMmcPciHcDriverBindingStart (
     Status = SdMmcHcCardDetect (PciIo, Slot, &MediaPresent);\r
     if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {\r
       continue;\r
-    } else if (MediaPresent == FALSE) {\r
-      DEBUG ((EFI_D_ERROR, "SdMmcHcCardDetect: No device attached in Slot[%d]!!!\n", Slot));\r
+    } else if (!MediaPresent) {\r
+      DEBUG ((DEBUG_INFO, "SdMmcHcCardDetect: No device attached in Slot[%d]!!!\n", Slot));\r
       continue;\r
     }\r
 \r
@@ -626,6 +648,7 @@ SdMmcPciHcDriverBindingStart (
     }\r
 \r
     Private->Slot[Slot].MediaPresent = TRUE;\r
+    Private->Slot[Slot].Initialized  = TRUE;\r
     RoutineNum = sizeof (mCardTypeDetectRoutineTable) / sizeof (CARD_TYPE_DETECT_ROUTINE);\r
     for (Index = 0; Index < RoutineNum; Index++) {\r
       Routine = &mCardTypeDetectRoutineTable[Index];\r
@@ -636,6 +659,28 @@ SdMmcPciHcDriverBindingStart (
         }\r
       }\r
     }\r
+    //\r
+    // This card doesn't get initialized correctly.\r
+    //\r
+    if (Index == RoutineNum) {\r
+      Private->Slot[Slot].Initialized = FALSE;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Enable 64-bit DMA support in the PCI layer if this controller\r
+  // supports it.\r
+  //\r
+  if (Support64BitDma) {\r
+    Status = PciIo->Attributes (\r
+                      PciIo,\r
+                      EfiPciIoAttributeOperationEnable,\r
+                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,\r
+                      NULL\r
+                      );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN, "SdMmcPciHcDriverBindingStart: failed to enable 64-bit DMA (%r)\n", Status));\r
+    }\r
   }\r
 \r
   //\r
@@ -643,7 +688,7 @@ SdMmcPciHcDriverBindingStart (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
+                  TPL_NOTIFY,\r
                   ProcessAsyncTaskList,\r
                   Private,\r
                   &Private->TimerEvent\r
@@ -683,7 +728,7 @@ SdMmcPciHcDriverBindingStart (
                   NULL\r
                   );\r
 \r
-  DEBUG ((EFI_D_INFO, "SdMmcPciHcDriverBindingStart: %r End on %x\n", Status, Controller));\r
+  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStart: %r End on %x\n", Status, Controller));\r
 \r
 Done:\r
   if (EFI_ERROR (Status)) {\r
@@ -764,7 +809,7 @@ SdMmcPciHcDriverBindingStop (
   LIST_ENTRY                          *NextLink;\r
   SD_MMC_HC_TRB                       *Trb;\r
 \r
-  DEBUG ((EFI_D_INFO, "SdMmcPciHcDriverBindingStop: Start\n"));\r
+  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStop: Start\n"));\r
 \r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
@@ -838,7 +883,7 @@ SdMmcPciHcDriverBindingStop (
 \r
   FreePool (Private);\r
 \r
-  DEBUG ((EFI_D_INFO, "SdMmcPciHcDriverBindingStop: End with %r\n", Status));\r
+  DEBUG ((DEBUG_INFO, "SdMmcPciHcDriverBindingStop: End with %r\n", Status));\r
 \r
   return Status;\r
 }\r
@@ -920,6 +965,10 @@ SdMmcPassThruPassThru (
     return EFI_NO_MEDIA;\r
   }\r
 \r
+  if (!Private->Slot[Slot].Initialized) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   Trb = SdMmcCreateTrb (Private, Slot, Packet, Event);\r
   if (Trb == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -935,7 +984,7 @@ SdMmcPassThruPassThru (
   // Wait async I/O list is empty before execute sync I/O operation.\r
   //\r
   while (TRUE) {\r
-    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     if (IsListEmpty (&Private->Queue)) {\r
       gBS->RestoreTPL (OldTpl);\r
       break;\r
@@ -1237,13 +1286,17 @@ SdMmcPassThruResetDevice (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-    if (!Private->Slot[Slot].MediaPresent) {\r
-      return EFI_NO_MEDIA;\r
-    }\r
+  if (!Private->Slot[Slot].MediaPresent) {\r
+    return EFI_NO_MEDIA;\r
+  }\r
+\r
+  if (!Private->Slot[Slot].Initialized) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
   //\r
   // Free all async I/O requests in the queue\r
   //\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   for (Link = GetFirstNode (&Private->Queue);\r
        !IsNull (&Private->Queue, Link);\r