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
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
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
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.