Device Driver Tutorial

Defining the Character and Block Operations Structure

The cb_ops(9S) structure initializes standard character and block interfaces. See the cb_ops(9S) man page to learn what each element is and what the value of each element should be. This dummy driver does not use all of the elements in the cb_ops(9S) structure. See the description that follows the code sample.

When you name this structure, use the same dummy_ prefix that you used for the names of the autoconfiguration routines and the names of the user context routines. Prepend the static type modifier to the declaration.

The following code is the cb_ops(9S) structure that you should enter into your dummy.c file:

static struct cb_ops dummy_cb_ops = {
    dummy_open,
    dummy_close,
    nodev,              /* no strategy - nodev returns ENXIO */
    nodev,              /* no print */
    nodev,              /* no dump */
    dummy_read,
    dummy_write,
    nodev,              /* no ioctl */
    nodev,              /* no devmap */
    nodev,              /* no mmap */
    nodev,              /* no segmap */
    nochpoll,           /* returns ENXIO for non-pollable devices */
    dummy_prop_op,
    NULL,               /* streamtab struct; if not NULL, all above */
                        /* fields are ignored */
    D_NEW | D_MP,       /* compatibility flags: see conf.h */
    CB_REV,             /* cb_ops revision number */
    nodev,              /* no aread */
    nodev               /* no awrite */
};

Enter the names of the open(9E) and close(9E) entry points for this driver as the values of the first two elements of this structure. Enter the names of the read(9E) and write(9E) entry points for this driver as the values of the sixth and seventh elements of this structure. Enter the name of the prop_op(9E) entry point for this driver as the value of the thirteenth element in this structure.

The strategy(9E), print(9E), and dump(9E) routines are for block drivers only. This dummy driver does not define these three routines because this driver is a character driver. This driver does not define an ioctl(9E) entry point because this driver does not use I/O control commands. This driver does not define devmap(9E), mmap(9E), or segmap(9E) entry points because this driver does not support memory mapping. This driver does not does not define aread(9E) or awrite(9E) entry points because this driver does not perform any asynchronous reads or writes. Initialize all of these unused function elements to nodev(9F). The nodev(9F) function returns the ENXIO error code.

Specify the nochpoll(9F) function for the chpoll(9E) element of the cb_ops(9S) structure because this driver is not for a pollable device. Specify NULL for the streamtab(9S) STREAMS entity declaration structure because this driver is not a STREAMS driver.

The compatibility flags are defined in the conf.h header file. The D_NEW flag means this driver is a new-style driver. The D_MP flag means this driver safely allows multiple threads of execution. All drivers must be multithreaded-safe, and must specify this D_MP flag. The D_64BIT flag means this driver supports 64-bit offsets and block numbers. See the conf.h header file for more compatibility flags.

The CB_REV element of the cb_ops(9S) structure is the cb_ops(9S) revision number. CB_REV is defined in the devops.h header file.