6.2.5 Bus driver protocol and child management

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.

Figure 14-Bus driver protocol management

The following sections describe the subtle differences in child handle creation for each of the bus driver types.