13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** @file 23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BDS Lib functions which relate with connect the device 33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 43cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiCopyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR> 53cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiThis program and the accompanying materials 63cbfba02fef9dae07a041fdbf2e89611d72d6f90David Weiare licensed and made available under the terms and conditions of the BSD License 73cbfba02fef9dae07a041fdbf2e89611d72d6f90David Weiwhich accompanies this distribution. The full text of the license may be found at 83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Weihttp://opensource.org/licenses/bsd-license.php 93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 103cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 113cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include "InternalBdsLib.h" 163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function will connect all the system driver to controller 203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei first, and then special connect the default console, this make 213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei sure all the system controller available and the platform default 223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei console connected. 233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 253cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID 263cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 273cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibConnectAll ( 283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Connect the platform console first 333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllDefaultConsoles (); 353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Generic way to connect all the drivers 383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllDriversToAllControllers (); 403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Here we have the assumption that we have already had 433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // platform default console 443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllDefaultConsoles (); 463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function will connect all the system drivers to all controllers 513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei first, and then connect all the console devices the system current 523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei have. After this we should get all the device work and console available 533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if the system have console device. 543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 563cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID 573cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibGenericConnectAll ( 583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Most generic way to connect all the drivers 633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllDriversToAllControllers (); 653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllConsoles (); 663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function will create all handles associate with every device 703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei path node. If the handle associate with one device path node can not 713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei be created successfully, then still give chance to do the dispatch, 723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei which load the missing drivers if possible. 733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param DevicePathToConnect The device path which will be connected, it can be 753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei a multi-instance device path 763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS All handles associate with every device path node 783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei have been created 793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles 803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_NOT_FOUND Create the handle associate with one device path 813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei node failed 823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 843cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 853cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 863cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibConnectDevicePath ( 873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect 883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_DEVICE_PATH_PROTOCOL *DevicePath; 923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; 933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_DEVICE_PATH_PROTOCOL *Instance; 943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; 953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_DEVICE_PATH_PROTOCOL *Next; 963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE Handle; 973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE PreviousHandle; 983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Size; 993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_TPL CurrentTpl; 1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (DevicePathToConnect == NULL) { 1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CurrentTpl = EfiGetCurrentTpl (); 1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DevicePath = DuplicateDevicePath (DevicePathToConnect); 1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (DevicePath == NULL) { 1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_OUT_OF_RESOURCES; 1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyOfDevicePath = DevicePath; 1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // The outer loop handles multi instance device paths. 1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Only console variables contain multiple instance device paths. 1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // After this call DevicePath points to the next Instance 1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Instance = GetNextDevicePathInstance (&DevicePath, &Size); 1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Instance == NULL) { 1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (CopyOfDevicePath); 1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_OUT_OF_RESOURCES; 1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Next = Instance; 1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei while (!IsDevicePathEndType (Next)) { 1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Next = NextDevicePathNode (Next); 1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SetDevicePathEndNode (Next); 1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Start the real work of connect with RemainingDevicePath 1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PreviousHandle = NULL; 1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the handle that best matches the Device Path. If it is only a 1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // partial match the remaining part of the device path is returned in 1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // RemainingDevicePath. 1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei RemainingDevicePath = Instance; 1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle); 1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Handle == PreviousHandle) { 1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // If no forward progress is made try invoking the Dispatcher. 1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // A new FV may have been added to the system an new drivers 1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // may now be found. 1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Status == EFI_SUCCESS means a driver was dispatched 1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Status == EFI_NOT_FOUND means no new drivers were dispatched 1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (CurrentTpl == TPL_APPLICATION) { 1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Dispatch calls LoadImage/StartImage which cannot run at TPL > TPL_APPLICATION 1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gDS->Dispatch (); 1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Always return EFI_NOT_FOUND here 1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // to prevent dead loop when control handle is found but connection failded case 1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_NOT_FOUND; 1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 1703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PreviousHandle = Handle; 1713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Connect all drivers that apply to Handle and RemainingDevicePath, 1733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // the Recursive flag is FALSE so only one level will be expanded. 1743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Do not check the connect status here, if the connect controller fail, 1763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // then still give the chance to do dispatch, because partial 1773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // RemainingDevicepath may be in the new FV 1783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1. If the connect fail, RemainingDevicepath and handle will not 1803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // change, so next time will do the dispatch, then dispatch's status 1813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // will take effect 1823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2. If the connect success, the RemainingDevicepath and handle will 1833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // change, then avoid the dispatch, we have chance to continue the 1843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // next connection 1853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE); 1873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Loop until RemainingDevicePath is an empty device path 1913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath)); 1933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while (DevicePath != NULL); 1953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (CopyOfDevicePath != NULL) { 1973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (CopyOfDevicePath); 1983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // All handle with DevicePath exists in the handle database 2013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 2043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 2063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function will connect all current system handles recursively. 2073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei gBS->ConnectController() service is invoked for each handle exist in system handler buffer. 2093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei If the handle is bus type handler, all childrens also will be connected recursively 2103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei by gBS->ConnectController(). 2113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS All handles and it's child handle have been connected 2133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). 2143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 2163cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 2173cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 2183cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibConnectAllEfi ( 2193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 2203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 2213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 2223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 2233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN HandleCount; 2243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE *HandleBuffer; 2253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Index; 2263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateHandleBuffer ( 2283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei AllHandles, 2293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 2303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 2313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleCount, 2323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleBuffer 2333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 2343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 2353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Index = 0; Index < HandleCount; Index++) { 2393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); 2403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (HandleBuffer != NULL) { 2433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (HandleBuffer); 2443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 2473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 2483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 2503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function will disconnect all current system handles. 2513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei gBS->DisconnectController() is invoked for each handle exists in system handle buffer. 2533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei If handle is a bus type handle, all childrens also are disconnected recursively by 2543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei gBS->DisconnectController(). 2553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS All handles have been disconnected 2573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). 2583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 2603cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 2613cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 2623cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibDisconnectAllEfi ( 2633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 2643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 2653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 2663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 2673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN HandleCount; 2683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE *HandleBuffer; 2693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Index; 2703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Disconnect all 2733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateHandleBuffer ( 2753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei AllHandles, 2763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 2773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 2783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleCount, 2793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleBuffer 2803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 2813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 2823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Index = 0; Index < HandleCount; Index++) { 2863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); 2873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (HandleBuffer != NULL) { 2903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (HandleBuffer); 2913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 2943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 2953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 2983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Connects all drivers to all controllers. 2993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function make sure all the current system driver will manage 3003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the correspoinding controllers if have. And at the same time, make 3013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei sure all the system controllers have driver to manage it if have. 3023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 3043cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID 3053cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 3063cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibConnectAllDriversToAllControllers ( 3073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 3083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 3093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 3103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 3133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Connect All EFI 1.10 drivers following EFI 1.10 algorithm 3153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BdsLibConnectAllEfi (); 3173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check to see if it's possible to dispatch an more DXE drivers. 3203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // The BdsLibConnectAllEfi () may have made new DXE drivers show up. 3213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // If anything is Dispatched Status == EFI_SUCCESS and we will try 3223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // the connect again. 3233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gDS->Dispatch (); 3253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while (!EFI_ERROR (Status)); 3273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 3293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 3323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Connect the specific Usb device which match the short form device path, 3333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei and whose bus is determined by Host Controller (Uhci or Ehci). 3343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param HostControllerPI Uhci (0x00) or Ehci (0x20) or Both uhci and ehci 3363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (0xFF) 3373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param RemainingDevicePath a short-form device path that starts with the first 3383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei element being a USB WWID or a USB Class device 3393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei path 3403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @return EFI_INVALID_PARAMETER RemainingDevicePath is NULL pointer. 3423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei RemainingDevicePath is not a USB device path. 3433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Invalid HostControllerPI type. 3443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @return EFI_SUCCESS Success to connect USB device 3453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @return EFI_NOT_FOUND Fail to find handle for USB controller to connect. 3463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 3483cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 3493cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 3503cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBdsLibConnectUsbDevByShortFormDP( 3513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINT8 HostControllerPI, 3523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 3533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 3543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 3553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE *HandleArray; 3573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN HandleArrayCount; 3583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Index; 3593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_PCI_IO_PROTOCOL *PciIo; 3603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT8 Class[3]; 3613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BOOLEAN AtLeastOneConnected; 3623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check the passed in parameters 3653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (RemainingDevicePath == NULL) { 3673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 3683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) || 3713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP) 3723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP) 3733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei )) { 3743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 3753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (HostControllerPI != 0xFF && 3783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HostControllerPI != 0x00 && 3793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HostControllerPI != 0x20) { 3803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 3813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the usb host controller firstly, then connect with the remaining device path 3853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei AtLeastOneConnected = FALSE; 3873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateHandleBuffer ( 3883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ByProtocol, 3893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiPciIoProtocolGuid, 3903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 3913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleArrayCount, 3923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleArray 3933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 3943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 3953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Index = 0; Index < HandleArrayCount; Index++) { 3963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->HandleProtocol ( 3973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HandleArray[Index], 3983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiPciIoProtocolGuid, 3993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&PciIo 4003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 4013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 4023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check whether the Pci device is the wanted usb host controller 4043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class); 4063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 4073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((PCI_CLASS_SERIAL == Class[2]) && 4083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (PCI_CLASS_SERIAL_USB == Class[1])) { 4093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) { 4103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->ConnectController ( 4113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HandleArray[Index], 4123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 4133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei RemainingDevicePath, 4143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FALSE 4153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 4163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR(Status)) { 4173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei AtLeastOneConnected = TRUE; 4183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (HandleArray != NULL) { 4263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (HandleArray); 4273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (AtLeastOneConnected) { 4303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 4313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_NOT_FOUND; 4353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 436