19.3.2 Driver Binding Protocol Start() and Stop()
The Start()
service of the Driver Binding Protocol for a USB device driver
opens the USB I/O Protocol with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
The service then installs the I/O abstraction protocol for the USB device or
host controller onto the handle on which the EFI_USB_IO_PROTOCOL
is installed.
19.3.2.1 Example using a USB mass storage device
This discussion provides detailed guidance on how to implement a USB device driver. It uses a USB mass storage device as an example. For example, suppose this mass storage device has the following four endpoints:
- One control endpoint
- One interrupt endpoint
- Two bulk endpoints
For the interrupt endpoint, it is synchronous. For the bulk endpoints, one is
an input endpoint and the other is an output endpoint. The following
discussions cover how to implement the Start()
and Stop()
driver binding
protocol services and UEFI Block I/O protocol.
This example shows a portion of the private context data structure for a USB mass storage device driver. See Chapter 8 of this guide for more information about design guidelines for private context data structures.
Example 207-USB mass storage driver private context data structure
#include <Uefi.h>
#include <Protocol/UsbIo.h>
#include <Protocol/BlockIo.h>
typedef struct {
UINT64 Signature;
EFI_BLOCK_IO_PROTOCOL BlockIO;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
EFI_USB_ENDPOINT_DESCRIPTOR BulkInEndpointDescriptor;
EFI_USB_ENDPOINT_DESCRIPTOR BulkOutEndpointDescriptor;
EFI_USB_ENDPOINT_DESCRIPTOR InterruptEndpointDescriptor;
} USB_MASS_STORAGE_DEVICE;
19.3.2.2 Example implementing Driver Binding Start()
The following steps are performed in the Driver Binding Protocol Start()
service.
- Open the USB I/O Protocol on ControllerHandle
EFI_OPEN_PROTOCOL_BY_DRIVER
. - Get the interface descriptor using the ##### EFI_USB_IO_PROTOCOL.UsbGetInterfaceDescriptor() service.
Prepare the private data structure.
This private data structure is in typeUSB_MASS_STORAGE_DEVICE
and has fields for the interface descriptor, endpoint descriptor, and others. This step allocates memory for the private data structure and does the required initializations-for example, setting up the Signature, UsbIo, and InterfaceDescriptor fields.Parse the interface descriptor.
In this step, the USB device driver parses the InterfaceDescriptor that was obtained in step 2, and verifies that all bulk and interrupt endpoints exit. The NumEndpoints field in InterfaceDescriptor indicates how many endpoints are in this USB interface. Next, the endpoint descriptors are retrieved one by one by using theUsbGetEndpointDescriptor()
service. Then, the Attributes and EndpointAddress fields in EndpointDescriptor are evaluated to determine the type of endpoint.- Install the Block I/O protocol.
19.3.2.3 Example implementing Driver Binding Stop()
The Driver Binding Protocol Stop()
service performs the reverse steps of the
Start()
service. Continuing with the previous example, the Stop()
service
uninstalls the Block I/O Protocol and closes the USB I/O Protocol. It also
frees various allocated resources such as the private data structure.