]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Hand/Handle.c
MdeModulePkg/DxeCore: Fixed Interface returned by CoreOpenProtocol
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Handle.c
index 6708ef8729ace640424f08c2296a90785c25798f..3ed187b27949d3b5d79b28ad52050f73554e1e06 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI handle & protocol handling.\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2017, 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
@@ -72,15 +72,20 @@ CoreValidateHandle (
   )\r
 {\r
   IHANDLE             *Handle;\r
+  LIST_ENTRY          *Link;\r
 \r
-  Handle = (IHANDLE *)UserHandle;\r
-  if (Handle == NULL) {\r
+  if (UserHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (Handle->Signature != EFI_HANDLE_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
+\r
+  for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {\r
+    Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
+    if (Handle == (IHANDLE *) UserHandle) {\r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
-  return EFI_SUCCESS;\r
+\r
+  return EFI_INVALID_PARAMETER;\r
 }\r
 \r
 \r
@@ -428,11 +433,12 @@ CoreInstallProtocolInterfaceNotify (
     // in the system\r
     //\r
     InsertTailList (&gHandleList, &Handle->AllHandles);\r
-  }\r
-\r
-  Status = CoreValidateHandle (Handle);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
+  } else {\r
+    Status = CoreValidateHandle (Handle);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));\r
+      goto Done;\r
+    }\r
   }\r
 \r
   //\r
@@ -491,6 +497,7 @@ Done:
     if (Prot != NULL) {\r
       CoreFreePool (Prot);\r
     }\r
+    DEBUG((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));\r
   }\r
 \r
   return Status;\r
@@ -513,8 +520,12 @@ Done:
                                  arguments to InstallProtocolInterface(). All the\r
                                  protocols are added to Handle.\r
 \r
+  @retval EFI_SUCCESS            All the protocol interface was installed.\r
+  @retval EFI_OUT_OF_RESOURCES   There was not enough memory in pool to install all the protocols.\r
+  @retval EFI_ALREADY_STARTED    A Device Path Protocol instance was passed in that is already present in\r
+                                 the handle database.\r
   @retval EFI_INVALID_PARAMETER  Handle is NULL.\r
-  @retval EFI_SUCCESS            Protocol interfaces successfully installed.\r
+  @retval EFI_INVALID_PARAMETER  Protocol is already installed on the handle specified by Handle.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -637,19 +648,16 @@ CoreDisconnectControllersUsingProtocolInterface (
   //\r
   do {\r
     ItemFound = FALSE;\r
-    for ( Link = Prot->OpenList.ForwardLink;\r
-          (Link != &Prot->OpenList) && !ItemFound;\r
-          Link = Link->ForwardLink ) {\r
+    for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
       OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
       if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
-        ItemFound = TRUE;\r
         CoreReleaseProtocolLock ();\r
         Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);\r
         CoreAcquireProtocolLock ();\r
-        if (EFI_ERROR (Status)) {\r
-           ItemFound = FALSE;\r
-           break;\r
+        if (!EFI_ERROR (Status)) {\r
+          ItemFound = TRUE;\r
         }\r
+        break;\r
       }\r
     }\r
   } while (ItemFound);\r
@@ -658,21 +666,17 @@ CoreDisconnectControllersUsingProtocolInterface (
     //\r
     // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items\r
     //\r
-    do {\r
-      ItemFound = FALSE;\r
-      for ( Link = Prot->OpenList.ForwardLink;\r
-            (Link != &Prot->OpenList) && !ItemFound;\r
-            Link = Link->ForwardLink ) {\r
-        OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
-        if ((OpenData->Attributes &\r
-            (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) {\r
-          ItemFound = TRUE;\r
-          RemoveEntryList (&OpenData->Link);\r
-          Prot->OpenListCount--;\r
-          CoreFreePool (OpenData);\r
-        }\r
+    for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {\r
+      OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
+      if ((OpenData->Attributes &\r
+          (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) {\r
+        Link = RemoveEntryList (&OpenData->Link);\r
+        Prot->OpenListCount--;\r
+        CoreFreePool (OpenData);\r
+      } else {\r
+        Link = Link->ForwardLink;\r
       }\r
-    } while (ItemFound);\r
+    }\r
   }\r
 \r
   //\r
@@ -1000,12 +1004,8 @@ CoreOpenProtocol (
   //\r
   // Check for invalid Interface\r
   //\r
-  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
-    if (Interface == NULL) {\r
-      return EFI_INVALID_PARAMETER;\r
-    } else {\r
-      *Interface = NULL;\r
-    }\r
+  if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
@@ -1072,12 +1072,6 @@ CoreOpenProtocol (
     goto Done;\r
   }\r
 \r
-  //\r
-  // This is the protocol interface entry for this protocol\r
-  //\r
-  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
-    *Interface = Prot->Interface;\r
-  }\r
   Status = EFI_SUCCESS;\r
 \r
   ByDriver        = FALSE;\r
@@ -1126,7 +1120,7 @@ CoreOpenProtocol (
     if (ByDriver) {\r
       do {\r
         Disconnect = FALSE;\r
-        for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) {\r
+        for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {\r
           OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
           if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
             Disconnect = TRUE;\r
@@ -1136,6 +1130,8 @@ CoreOpenProtocol (
             if (EFI_ERROR (Status)) {\r
               Status = EFI_ACCESS_DENIED;\r
               goto Done;\r
+            } else {\r
+              break;\r
             }\r
           }\r
         }\r
@@ -1171,8 +1167,28 @@ CoreOpenProtocol (
   }\r
 \r
 Done:\r
+\r
+  if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {\r
+    //\r
+    // Keep Interface unmodified in case of any Error\r
+    // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.\r
+    //\r
+    if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {\r
+      //\r
+      // EFI_ALREADY_STARTED is not an error for bus driver.\r
+      // Return the corresponding protocol interface.\r
+      //\r
+      *Interface = Prot->Interface;\r
+    } else if (Status == EFI_UNSUPPORTED) {\r
+      //\r
+      // Return NULL Interface if Unsupported Protocol.\r
+      //\r
+      *Interface = NULL;\r
+    }\r
+  }\r
+\r
   //\r
-  // Done. Release the database lock are return\r
+  // Done. Release the database lock and return\r
   //\r
   CoreReleaseProtocolLock ();\r
   return Status;\r