+/**\r
+ Connect the console device base on the variable ConVarName, if\r
+ device path of the ConVarName is multi-instance device path and\r
+ anyone of the instances is connected success, this function will\r
+ return success. \r
+ Dispatch service is called basing on input when the handle associate\r
+ with one device path node can not be created successfully. Since in\r
+ some cases we assume driver dependency does not exist and do not \r
+ need to call this service.\r
+\r
+ @param ConVarName Console related variable name, ConIn, ConOut,\r
+ ErrOut.\r
+ @param NeedDispatch Whether requires dispatch service during connection \r
+\r
+ @retval EFI_NOT_FOUND There is not any console devices connected\r
+ success\r
+ @retval EFI_SUCCESS Success connect any one instance of the console\r
+ device path base on the variable ConVarName.\r
+\r
+**/\r
+EFI_STATUS\r
+ConnectConsoleVariableInternal (\r
+ IN CHAR16 *ConVarName,\r
+ IN BOOLEAN NeedDispatch\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
+ UINTN VariableSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *Next;\r
+ EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
+ UINTN Size;\r
+ BOOLEAN DeviceExist;\r
+\r
+ Status = EFI_SUCCESS;\r
+ DeviceExist = FALSE;\r
+\r
+ //\r
+ // Check if the console variable exist\r
+ //\r
+ StartDevicePath = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &VariableSize\r
+ );\r
+ if (StartDevicePath == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CopyOfDevicePath = StartDevicePath;\r
+ do {\r
+ //\r
+ // Check every instance of the console variable\r
+ //\r
+ Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
+ if (Instance == NULL) {\r
+ FreePool (StartDevicePath);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ Next = Instance;\r
+ while (!IsDevicePathEndType (Next)) {\r
+ Next = NextDevicePathNode (Next);\r
+ }\r
+\r
+ SetDevicePathEndNode (Next);\r
+ //\r
+ // Connect the USB console\r
+ // USB console device path is a short-form device path that \r
+ // starts with the first element being a USB WWID\r
+ // or a USB Class device path\r
+ //\r
+ if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
+ ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
+ || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
+ )) {\r
+ Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);\r
+ if (!EFI_ERROR (Status)) {\r
+ DeviceExist = TRUE;\r
+ }\r
+ } else {\r
+ //\r
+ // Connect the instance device path\r
+ //\r
+ Status = ConnectDevicePathInternal (Instance, NeedDispatch);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Delete the instance from the console varialbe\r
+ //\r
+ BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);\r
+ } else {\r
+ DeviceExist = TRUE;\r
+ }\r
+ }\r
+ FreePool(Instance);\r
+ } while (CopyOfDevicePath != NULL);\r
+\r
+ FreePool (StartDevicePath);\r
+\r
+ if (!DeviceExist) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r