Writing Device Drivers

Appendix E Driver Code Layout Structure

This appendix presents the code layout structure of a typical driver. Sample structures and prototypes are displayed for a common device driver.

The code for a device driver is usually divided into the following files:

Header Files

Header files define data structures specific to the device (such as a structure representing the device registers), data structures defined by the driver for maintaining state information, defined constants (such as those representing the bits of the device registers), and macros (such as those defining the static mapping between the minor device number and the instance number).

Some of this information, such as the state structure, may only be needed by the device driver. This information should go in private header files that are only included by the device driver itself.

Any information that an application might require, such as the I/O control commands, should be in public header files. These are included by the driver and any applications that need information about the device.

There is no standard for naming private and public files. One possible convention is to name the private header file xximpl.h and the public header file xxio.h. Example E-1 and Example E-2 show the layout of these headers.


Example E-1 xximpl.h Header File

/* xximpl.h */
struct device_reg {
	 /* fields */
};
/* #define bits of the device registers...*/
struct xxstate {
	/* fields */
};
/* related #define statements */


Example E-2 xxio.h Header File

xxio.h Header File
/* xxio.h */
struct xxioctlreq {
	/* fields */
};
/* etc. */
#define XXIOC				(`b' << 8)
#define XXIOCTL_1 (XXIOC | 1)										/* description */
#define XXIOCTL_2 (XXIOC | 2)										/* description */

xx.c Files

A .c file for a device driver contains the data declarations and the code for the entry points of the driver. It contains the #include statements the driver needs, declares extern references, declares local data, sets up the cb_ops and dev_ops structures, declares and initializes the module configuration section, makes any other necessary declarations, and defines the driver entry points. The following sections describe these driver components. Example E-3 shows the layout of an xx.c file.


Example E-3 xx.c File

/* xx.c */
#include "xximpl.h"
#include "xxio.h"
#include <sys/ddi.h>							/* must include these two files */
#include <sys/sunddi.h>							/* and they must be the last system */
							/* includes */
/* forward declaration of entry points */

/* static declarations of cb_ops entry point functions...*/

static struct cb_ops xx_cb_ops = {
	/* set cb_ops fields */
};

/* static declarations of dev_ops entry point functions */
static struct dev_ops xx_ops = {
	/* set dev_ops fields*/
};

/* declare and initialize the module configuration section */
static struct modldrv modldrv = {
	/* set modldrv fields */
};
static struct modlinkage modlinkage = {
	/* set modlinkage fields */
};
int
_init(void)
{
	/* definition */
}
int
_info(struct modinfo *modinfop)
{
	/* definition */
}
int
_fini(void)
{
	/* definition */
}
static int
xxprobe(dev_info_t *dip)
{
	/* definition */
}
static int
xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	/* definition */
}
static int
xxdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
	/* definition */
}
static int
xxgetinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
   void **result)
{
	/* definition */
}
static int
xxopen(dev_t *devp, int flag, int otyp, cred_t *credp)
{
	/* definition */
}
static int
xxclose(dev_t dev, int flag, int otyp, cred_t *credp)
{
	/* definition */
}
static int
xxstrategy(struct buf *bp)
{
	/* definition */
}

/* for character-oriented devices */
static int
xxread(dev_t dev, struct uio *uiop, cred_t *credp)
{
	/* definition */
}
/* for asynchronous I/O */
static int
xxaread(dev_t dev, struct aio_req *aiop, cred_t *cred_p)
{
	/* definition */
}
static int
xxwrite(dev_t dev, struct uio *uiop, cred_t *credp)
{
	/* definition */
}

/* for asynchronous I/O */
static int
xxawrite(dev_t dev, struct aio_req *aiop, cred_t *cred_p)
{
	/* definition */
}
static int
xxioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t
*credp,
    int *rvalp)
{
	/* definition */
}

/* for memory-mapped character-oriented devices */
static int
xxdevmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t
len, size_t *maplen, uint_t model)
{
	/* definition */
}

/* for support of the poll(2) system call */
static int
xxchpoll(dev_t dev, short events, int anyyet, short *reventsp,
    struct pollhead **phpp)
{
	/* definition */
}

/* for drivers needing a xxprop_op routine */
static int
xxprop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
    int mod_flags, char *name, caddr_t valuep, int *lengthp)
{
	/* definition */
}

driver .conf Files

See driver.conf(4), sbus(4), pci(4). isa(4), eisa(4), and vme(4) for more information.