Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
  Previous   Contents   Next 
   
 
Chapter 11

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:

modlinkage(9S)

Contains the revision number and a list of drivers to dynamically load. It is used by mod_install in the _init routine to load the module into the kernel. Points to a modldrv(9S) or modlstrmod(9S).

modldrv(9S)

Contains information about the driver being loaded and points to the devops structure.

modlstrmod(9S)

Points to an fmodsw(9S) structure (which points to a streamtab(9S)). Only used by STREAMS modules.

dev_ops(9S)

Contains list of entry points for a driver, such as identify, attach, and info. Also points to a cb_ops(9S) structure.

cb_ops(9S)

Points to list of threadable entry points to driver, like open, close, read, write, ioctl. Also points to the streamtab.

streamtab(9S)

Points to the read and write queue init structures.

qinit(9S)

Points to the entry points of the STREAMS portion of the driver, such as put, srv, open, close, as well as the mod_info structure. These entry points only process messages.

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 */
};
 
 
 
  Previous   Contents   Next