A driver's executable is composed of one or more UDI driver modules, each of which can be separately loaded and executed (e.g., into separate addressing domains or protection/privilege domains). Driver writers need to consider the partitioning of their driver into modules in conjunction with the partitioning of driver instances into regions.
Each driver module handles some (mutually-exclusive) subset of the driver's region types. Each driver has one module, called the ``primary module'', which handles the driver's primary region. Additional modules, called secondary modules, may be defined by the driver.
Each UDI driver module has a single well-known global variable, named udi_init_info that describes the module's entry points and size requirements (see ``Driver initialization structure''). There are no global entry points into UDI drivers; all entries are through function pointers defined in udi_init_info.
The information specified in this section of the udiprops.txt file is used in the region, operation, control block, and other definitions pointed to by the udi_init_info structure definitions for each driver module.
|cmos_udi.c sample driver udiprops.txt (cont.)|
## ## Declare the driver's module(s) and region types. ## This driver has a single region in a single module. ##
|pseudod.c sample driver udiprops.txt (cont.)|
## ## Interface dependencies ## requires udi 0x101 requires udi_physio 0x101 requires udi_bridge 0x101 requires udi_gio 0x101
The region and module structure of the cmos_udi and pseudod drivers is apparent from the udiprops.txt declarations shown above. These declarations are used in the eventual definition of the required udi_init_info structure in the source code of each module of the driver.
All UDI drivers must first define the versions of each UDI interface used by the drivers, done in the requires declarations shown above, all of which point to version 1.0.0 interfaces defined in the Version 1.0.0 UDI Specifications.
Every UDI driver must declare at a minimum the versions of the four metalanguage interfaces shown used in the driver. These interfaces are all part of the UDI environment on the target system and are all present in a conforming UDI implementation. The driver code may or may not use all these interfaces, and in fact the two samples shown use only the udi_gio and udi_bridge interfaces.
Both of these drivers are single-module, single-region drivers as defined by the module and region declarations. Regions and modules are numbered (starting at zero) to provide an index to be used in the driver source code and subsequent declarations.
Similarly, the meta declarations show which defined metalanguages will be used by this driver and are also indexed; metalanguage indexes must be non-zero.
Both the region and metalanguage indexes are used in the subsequent operations declarations, which are used to construct the operations vector for each defined region.
Three types of operations declarations are permitted:
Most driver modules will have at least one parent and one child relationship, though they are not strictly required.
Drivers without parent operations are called ``orphans'' and control no real devices. Orphans may receive operations requests from other drivers or the UDI environment, but do not issue any operations requests outside the driver's defined regions. [Note that although the pseudod sample driver does not control any real devices, it still has a parent_bind_ops declaration because it simulates real output to a device.]
It is likewise permitted to have a driver with no child operations defined, but such code could not be considered a device driver since it receives no operation requests, interrupts, etc., to which it can respond. It is really an application running as a UDI driver.
Each of these define a possible communication channel relationship between the driver module in which they appear and another UDI module. These definitions are used in defining communications channels either between two regions defined by the driver (internal_bind_ops) or between a driver region and a region of another UDI driver module or core service provider.
In the sample drivers' udiprops.txt files above, two channel operations are defined. The possible channels defined are a channel to the GIO mapper in the UDI environment in which the driver acts as the child, and a channel to the bus bridge mapper in which the driver acts as the parent. Each channel uses the indexed metalanguage appropriate to the operations needed on the channel.
We'll discuss how these indexes are used in driver code and what these operations declarations mean in more detail below, when we discuss the udi_init_info structure required for each driver (see ``Driver initialization structure'').