Configuring STREAMS Drivers and Modules
This chapter contains information about configuring STREAMS drivers and modules into the Solaris operating environment. It describes how to configure a driver and a module for the STREAMS framework only. For more in-depth information on the general configuration mechanism, see Writing Device Drivers.
This chapter has the following organization:
Kernel Data Structures
The following sections contain descriptions of the pointer relationships maintained by the kernel and the various data structures used in STREAMS drivers. When the kernel accesses a driver, it uses a sequence of pointers in various data structures. It looks first at the data structure relationship, and then the entry point interface for loading the driver into the kernel and accessing the driver from the application level.
The order of data structures the kernel uses to get to a driver is as follows:
Each STREAMS driver or module contains the linkage connections for the various data structures which is a list of pointers to dev_ops(9S) structures. In each dev_ops(9S) structure is a pointer to the cb_ops(9S) structure. In the cb_ops(9S) structure contains a pointer to the streamtab struct. If the driver is not a STREAMS driver, streamtab is NULL. If the driver is a STREAMS driver, streamtab contains initialization routines for the driver.
modlinkage
The definition of modlinkage(9S) is:
struct modlinkage { int ml_rev; /* rev of loadable modules system */ void *ml_linkage[4]; /* NULL terminated list of linkage * structures */ }; |
modldrv
The definition of modldrv(9S) is:
struct modldrv { struct mod_ops *drv_modops; char *drv_linkinfo; struct dev_ops *drv_dev_ops; }; |
modlstrmod
The definition of modlstrmod(9S) is below. It does not point to dev_ops(9S) structures because modules can only be pushed onto an existing stream.
struct modlstrmod { struct mod_ops *strmod_modops; char *strmod_linkinfo; struct fmodsw *strmod_fmodsw; }; |
dev_ops
The dev_ops(9S) structure represents a specific class or type of device. Each dev_ops(9S) structure represents a unique device to the operating system. Each device has its own dev_ops(9S) structure, which in turn contains a cb_ops(9S) structure.
struct dev_ops { int devo_rev; /* Driver build version */ int devo_refcnt; /* device reference count */ int (*devo_getinfo)(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result); int (*devo_identify)(dev_info_t *dip); int (*devo_probe)(dev_info_t *dip); int (*devo_attach)(dev_info_t *dip, ddi_attach_cmd_t cmd); int (*devo_detach)(dev_info_t *dip, ddi_detach_cmd_t cmd); int (*devo_reset)(dev_info_t *dip, ddi_reset_cmd_t cmd); struct cb_ops *devo_cb_ops; /* cb_ops ptr for leaf driver*/ struct bus_ops *devo_bus_ops; /* ptr for nexus drivers */ }; |
cb_ops
The cb_ops(9S) structure is the SunOS 5 version of the cdevsw and bdevsw tables of previous versions of UNIX System V. It contains character and block device information and the driver entry points for non-STREAMS drivers.
struct cb_ops { int *cb_open)(dev_t *devp, int flag, int otyp, cred_t *credp); int (*cb_close)(dev_t dev, int flag, int otyp, cred_t *credp); int (*cb_strategy)(struct buf *bp); int (*cb_print)(dev_t dev, char *str); int (*cb_dump)(dev_t dev, caddr_t addr,daddr_t blkno, int nblk); int (*cb_read)(dev_t dev, struct uio *uiop, cred_t *credp); int (*cb_write)(dev_t dev, struct uio *uiop, cred_t *credp); int (*cb_ioctl)(dev_t dev, int cmd, int arg, int mode, cred_t *credp, int *rvalp); int (*cb_devmap)(dev_t dev, dev_info_t *dip, ddi_devmap_data_t *dvdp, ddi_devmap_cmd_t cmd, off_t offset, unsigned int len, unsigned int prot, cred_t *credp); int (*cb_mmap)(dev_t dev, off_t off, int prot); int (*cb_segmap)(dev_t dev, off_t off, struct as *asp, caddr_t *addrp, off_t len, unsigned int prot, unsigned int maxprot, unsigned int flags, cred_t *credp); int (*cb_chpoll)(dev_t dev, short events, int anyyet, short *reventsp, struct pollhead **phpp); int (*cb_prop_op)(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, char *name, caddr_t valuep, int *length); struct streamtab *cb_str; /* streams information */ /* * The cb_flag fields are here to tell the system a bit about * the device. The bit definitions are in <sys/conf.h>. */ int cb_flag; /* driver compatibility flag */ }; |