]> 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 0a2f034cfca1c32a5790286c8dcfabe6dfac2eb5..23faec5e2be0bbc9a317130822eecb0388f4fd4f 100644 (file)
@@ -4,7 +4,7 @@
 \r
   It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.\r
 \r
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -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
@@ -613,8 +635,10 @@ SdMmcPciHcDriverBindingStart (
     // Check whether there is a SD/MMC card attached\r
     //\r
     Status = SdMmcHcCardDetect (PciIo, Slot, &MediaPresent);\r
-    if ((Status == EFI_MEDIA_CHANGED) && (MediaPresent == FALSE)) {\r
-      DEBUG ((EFI_D_ERROR, "SdMmcHcCardDetect: No device attached in Slot[%d]!!!\n", Slot));\r
+    if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {\r
+      continue;\r
+    } else if (!MediaPresent) {\r
+      DEBUG ((DEBUG_INFO, "SdMmcHcCardDetect: No device attached in Slot[%d]!!!\n", Slot));\r
       continue;\r
     }\r
 \r
@@ -624,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
@@ -634,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
@@ -641,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
@@ -681,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
@@ -762,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
@@ -836,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
@@ -918,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
@@ -933,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
@@ -1235,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