The management of I/O-related protocols by a bus driver is very similar to the management of I/O-related protocol for device drivers described in Section 6.1.6. A bus driver opens one or more I/O-related protocols on the controller handle for the bus controller, creates one or more child handles and installs one or more I/O-related protocols. If the child handle represents a physical device, a Device Path Protocol must also be installed onto the child handle. The child handle is also required to open the parent I/O protocol with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
.
Some types of bus drivers can produce a single child handle each time Start()
is called, but only if the RemainingDevicePath passed into Start()
represents a valid child device. This distinction means that it may take multiple calls to Start()
to produce all the child handles. If RemainingDevicePath is NULL
, all remaining child handles are created at once.
When a bus driver opens an I/O-related protocol on the controller handle, it typically uses an open mode of EFI_OPEN_PROTOCOL_BY_DRIVER
. However, depending on the type of bus driver, a return code of EFI_ALREADY_STARTED
from OpenProtocol()
may be acceptable. If a device driver gets this return code, then the device driver should not manage the controller handle. If a bus driver gets this return code, then it means that the bus driver has already connected to the controller handle.
The figure below shows a simple bus driver that consumes Protocol A
from a bus controller handle and creates N child handles with a Device Path Protocol
and Protocol B
. The Stop()
function is responsible for destroying the child handles by removing Protocol B and the Device Path Protocol
. Protocol A
is first opened EFI_OPEN_PROTOCOL_BY_DRIVER
so Protocol A cannot be requested by any other drivers. Then, as each child handle is created, the child handle opens Protocol A
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
. Using this attribute records the parent-child relationship in the handle database, so this information can be extracted if needed. The parent-child links are used by DisconnectController()
when a request is made to stop a bus controller.
The following sections describe the subtle differences in child handle creation for each of the bus driver types.