By passing the handle of a specific controller into
ConnectController(), UEFI follows a specific process to determine which driver(s) manage the controller. For reference, the following example is the definition of
Connects one or more drivers to a controller.
@param ControllerHandle The handle of the controller to which driver(s) are to be connected.
@param DriverImageHandle A pointer to an ordered list handles that support
@param RemainingDevicePath A pointer to the device path that specifies a child of the controller
specified by ControllerHandle.
@param Recursive If TRUE, then ConnectController() is called recursively until the
entire tree of controllers below the controller specified by
ControllerHandle have been created. If FALSE, then the tree of
controllers is only expanded one level.
@retval EFI_SUCCESS 1) One or more drivers were connected to
2) No drivers were connected to ControllerHandle,
But RemainingDevicePath is not NULL, and it is
an End Device Path Node.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL
Instances present in the system.
2) No drivers were connected to ControllerHandle.
(EFIAPI * EFI_CONNECT_CONTROLLER)(
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE *DriverImageHandle, OPTIONAL
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, OPTIONAL
IN BOOLEAN Recursive
The connection is a two-phase process:
- 1.Construct an ordered list of driver handles from highest to lowest priority.
- 2.Attempt to connect the drivers to a controller in priority order from highest to lowest.
The following table lists the steps for phase one; driver connection precedence rules. Much of this information is in the UEFI Specification where the UEFI boot service
Phase two of the connection process checks each driver in the ordered list to see if it supports the controller. This check calls the
Supported()service of the driver's Driver Binding Protocol and passes in the ControllerHandle and the RemainingDevicePath. If successful, the
Start()service calls the Driver Binding Protocol and passes in the ControllerHandle and RemainingDevicePath. Each driver in the list is given an opportunity to connect, even if a prior driver connected successfully. However, if a driver with higher priority had already connected and opened the parent I/O protocol with exclusive access, the other drivers would not be able to connect if they also require exclusive access to the parent I/O protocol.
Use this type of connection process because the order in which drivers are installed into the handle database is not deterministic. Drivers can be unloaded and reloaded later, which changes the order of the drivers in the handle database.
These precedent rules assume that the relevant drivers to be considered are loaded into memory. This case may not be true for all systems. Large systems, for example, may limit "bootable" devices to a subset of the total number of devices in the system.
ConnectController()function can be called several times during the UEFI initialization. Use it to connect consoles, devices required to load drivers from the driver list, and to connect devices required for the boot options to be processed by the boot manager.