Extensible Device Interface Documentation
3
Copyright (c) 2006 Eli Gottlieb. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the file entitled "COPYING".Notes on types: All integer types are signed by default, the size of pointer types is determined by hardware and all data structures - including arrays - are packed. Whenever a numerical NULL value is referred to, the value 0 for the appropriate type is meant.
Overview
The Extensible Driver Interface (EDI) is a device driver interface standard which aims to maximize portability of device drivers between operating systems while minimizing the amount of standardized functionality and supporting non-standard functionality. It does this by standardizing only a small, fixed interface to the level of source-portability. Drivers can use this standardized interface to converse with the operating system kernel about the hardware run by the driver - and about non-standardized functionality - through the EDI runtime implementing this interface. Anything not explicitly standardized under EDI is up to operating system developers.
The chief way in which EDI does this is through the use of a semi-object-oriented class model. The core of the standardized EDI interface is a set of functions for registering, instantiating and destroying classes, along with obtaining function pointers to their methods. To EDI, a class is a set of functions associated with a constructor and a destructor. These routines are implemented by either a driver or a runtime, and are said to be "owned" by their implementor. Having all class routines (including allocation of memory) be implemented by the class owner allows driver and operating system developers as much leeway as possible in implementing EDI-compatible drivers and EDI runtimes.
EDI also requires that runtimes implement a subset of POSIX threading. This could mean that processor time is multiplexed between different drivers or within drivers. It could mean that drivers are processes like any other, but with special system calls (EDI itself). It could mean something entirely else. As long as the semantics of the POSIX Threads subset work from the driver's point of view and different threads can see each other's memory, anything goes.
EDI also standardizes several classes for runtimes to implement. These deal with talking to hardware via port I/O, memory mapped I/O, interrupt handling and Direct Memory Access hardware. For DMA a stream model is used, while port I/O and memory mapped I/O follow their own, self-evident models. A standardized class for interrupt handling is also provided, though runtimes can decide on a fair deal of its behavior.
To use EDI a driver exports two functions from its binary: a driver_init_t() and a driver_finish_t(). When the runtime finishes creating an EDI object for a driver, it calls driver_init() with a list of objects it thinks the driver should run with. This list can be created however suits the runtime. The driver reads this list and initializes itself and its classes, possibly calling edi_negotiate_resources() to obtain more resources. If the runtime passed an empty resource list it must return true from edi_negotiate_resources(). Once the driver has initialized itself, it returns an edi_initialization_t structure containing a list of its classes the runtime can use, along with its quota function. If the driver can't properly initialize, it should return NULL or 0 in any field of edi_initialization_t to indicate this, and the runtime will shut EDI and the driver down. Once the driver has initialized, the runtime may create instances of the classes given it and use these to call driver functionality.
When the driver is finished it calls shutdown_edi(), optionally destroying all objects first. If it doesn't destroy them, the runtime should. The runtime can also call shutdown_edi() at any time, and shutdown_edi() should always call the driver's driver_finish() routine to allow the driver to clean up.
In conclusion, the Extensible Driver Interface tries to provide the greatest possible design and programming options to operating system kernels and the greatest possible portability to drivers by standardizing a small interface for doing only the things common to all device drivers on all operating systems (talking to hardware) and for checking for other functionality. It mostly does this through its object model and through the standardized classes the EDI runtime must provide, while allowing both driver and runtime to require each other to implement nonstandard classes if they truly require the functionality.
Generated on Fri Oct 27 20:00:03 2006 for Extensible Device Interface by
1.4.7