--- /dev/null
+/** @file\r
+ BDS Lib functions which relate with connect the device\r
+\r
+Copyright (c) 2004 - 2008, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Platform.h"\r
+\r
+\r
+EFI_STATUS ScanDeviceHandles(EFI_HANDLE ControllerHandle,\r
+ UINTN *HandleCount,\r
+ EFI_HANDLE **HandleBuffer,\r
+ UINT32 **HandleType)\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN HandleIndex;\r
+ EFI_GUID **ProtocolGuidArray;\r
+ UINTN ArrayCount;\r
+ UINTN ProtocolIndex;\r
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
+ UINTN OpenInfoCount;\r
+ UINTN OpenInfoIndex;\r
+ UINTN ChildIndex;\r
+\r
+ *HandleCount = 0;\r
+ *HandleBuffer = NULL;\r
+ *HandleType = NULL;\r
+\r
+ //\r
+ // Retrieve the list of all handles from the handle database\r
+ //\r
+ Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, HandleCount, HandleBuffer);\r
+ if (EFI_ERROR (Status)) goto Error;\r
+\r
+ *HandleType = AllocatePool (*HandleCount * sizeof (UINT32));\r
+ if (*HandleType == NULL) goto Error;\r
+\r
+ for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
+ (*HandleType)[HandleIndex] = EFI_HANDLE_TYPE_UNKNOWN;\r
+ //\r
+ // Retrieve the list of all the protocols on each handle\r
+ //\r
+ Status = gBS->ProtocolsPerHandle (\r
+ (*HandleBuffer)[HandleIndex],\r
+ &ProtocolGuidArray,\r
+ &ArrayCount\r
+ );\r
+ if (!EFI_ERROR (Status)) { \r
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) \r
+ {\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid))\r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_IMAGE_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid))\r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid)) \r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid)) \r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid)) \r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) \r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;\r
+ }\r
+\r
+ if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid)) \r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DEVICE_HANDLE;\r
+ }\r
+\r
+ //\r
+ // Retrieve the list of agents that have opened each protocol\r
+ //\r
+ Status = gBS->OpenProtocolInformation (\r
+ (*HandleBuffer)[HandleIndex],\r
+ ProtocolGuidArray[ProtocolIndex],\r
+ &OpenInfo,\r
+ &OpenInfoCount\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
+\r
+ if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle)\r
+ {\r
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) \r
+ {\r
+ for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) \r
+ {\r
+ if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) \r
+ {\r
+ (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)\r
+ {\r
+ (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_PARENT_HANDLE;\r
+ for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) \r
+ {\r
+ if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) \r
+ {\r
+ (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ FreePool (OpenInfo);\r
+ }\r
+ }\r
+\r
+ FreePool (ProtocolGuidArray);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+Error:\r
+ if (*HandleType != NULL) {\r
+ FreePool (*HandleType);\r
+ }\r
+\r
+ if (*HandleBuffer != NULL) {\r
+ FreePool (*HandleBuffer);\r
+ }\r
+\r
+ *HandleCount = 0;\r
+ *HandleBuffer = NULL;\r
+ *HandleType = NULL;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS BdsLibConnectMostlyAllEfi()\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN AllHandleCount;\r
+ EFI_HANDLE *AllHandleBuffer;\r
+ UINTN Index;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINT32 *HandleType;\r
+ UINTN HandleIndex;\r
+ BOOLEAN Parent;\r
+ BOOLEAN Device;\r
+ EFI_PCI_IO_PROTOCOL* PciIo;\r
+ PCI_TYPE00 Pci;\r
+ \r
+ \r
+ Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &AllHandleCount, &AllHandleBuffer);\r
+ if (CheckError(Status, L"locating handle buffer")) \r
+ return Status;\r
+ \r
+ for (Index = 0; Index < AllHandleCount; Index++) \r
+ {\r
+ Status = ScanDeviceHandles(AllHandleBuffer[Index], &HandleCount, &HandleBuffer, &HandleType);\r
+ \r
+ if (EFI_ERROR (Status))\r
+ goto Done;\r
+ \r
+ Device = TRUE;\r
+ \r
+ if (HandleType[Index] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE)\r
+ Device = FALSE;\r
+ if (HandleType[Index] & EFI_HANDLE_TYPE_IMAGE_HANDLE)\r
+ Device = FALSE;\r
+ \r
+ if (Device) \r
+ { \r
+ Parent = FALSE;\r
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) \r
+ {\r
+ if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE)\r
+ Parent = TRUE;\r
+ }\r
+ \r
+ if (!Parent) \r
+ {\r
+ if (HandleType[Index] & EFI_HANDLE_TYPE_DEVICE_HANDLE) \r
+ {\r
+ Status = gBS->HandleProtocol (AllHandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
+ if (!EFI_ERROR (Status)) \r
+ {\r
+ Status = PciIo->Pci.Read (PciIo,EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);\r
+ if (!EFI_ERROR (Status))\r
+ {\r
+ if(IS_PCI_VGA(&Pci)==TRUE)\r
+ {\r
+ gBS->DisconnectController(AllHandleBuffer[Index], NULL, NULL);\r
+ }\r
+ }\r
+ }\r
+ Status = gBS->ConnectController(AllHandleBuffer[Index], NULL, NULL, TRUE);\r
+ }\r
+ }\r
+ }\r
+ \r
+ FreePool (HandleBuffer);\r
+ FreePool (HandleType);\r
+ }\r
+ \r
+Done:\r
+ FreePool (AllHandleBuffer);\r
+ return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+ Connects all drivers to all controllers.\r
+ This function make sure all the current system driver will manage\r
+ the correspoinding controllers if have. And at the same time, make\r
+ sure all the system controllers have driver to manage it if have.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BdsLibConnectAllDriversToAllControllers (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ do {\r
+ //\r
+ // Connect All EFI 1.10 drivers following EFI 1.10 algorithm\r
+ //\r
+ //BdsLibConnectAllEfi ();\r
+ BdsLibConnectMostlyAllEfi ();\r
+\r
+ //\r
+ // Check to see if it's possible to dispatch an more DXE drivers.\r
+ // The BdsLibConnectAllEfi () may have made new DXE drivers show up.\r
+ // If anything is Dispatched Status == EFI_SUCCESS and we will try\r
+ // the connect again.\r
+ //\r
+ Status = gDS->Dispatch ();\r
+\r
+ } while (!EFI_ERROR (Status));\r
+\r
+}\r