Implementing STREAMS drivers and modules in DDI 8

The following notes describe the main differences of STREAMS drivers and modules in DDI 8 compared to previous releases of the DDI (the device driver interface in UnixWare) and the ODDI (the device driver interface in OpenServer). They will be useful if you are writing new STREAMS drivers or modules, or you are porting existing drivers or modules to DDI 8. These notes should be read in conjunction with ``Porting drivers to DDI 8''. If you are porting STREAMS drivers or modules from SCO OpenServer 5, you should also read ``Porting SCO OpenServer 5 STREAMS drivers and modules''.

Registering STREAMS drivers and modules

DDI 8 STREAMS drivers and modules must register themselves with the system by passing a drvinfo(D4) structure to the drv_attach(D3) function which is called from their _load(D2) entry point routine. This structure identifies the type of driver, its entry points, and other driver properties of which the kernel must be aware.

In DDI 8, the streamtab(D4str) structure is made available through the drv_str member of drvinfo instead of being a global variable. The drv_str member points to a streamtab structure for STREAMS drivers and modules. It must be set to NULL for non-STREAMS drivers. The D_MOD flag must be set in the drv_flags member of drvinfo to distinguish a STREAMS module from a STREAMS driver. Other flags (D_MP, D_HOT, D_UPF) may be set depending on the properties of the driver. See the drvinfo(D4) manual page for details. Note that if a kernel module wants to act as both a STREAMS module and a STREAMS driver, it must call drv_attach twice, once with D_MOD set and once without.

Driver entry routines

Every DDI 8 STREAMS driver or module requires the following entry point routines: close(D2str), devinfo(D2str), _load(D2str), open(D2str), put(D2str), and _unload(D2str) STREAMS drivers that control some hardware device, such as a directly connected adapter, are considered to be hardware drivers. They must provide a config(D2) entry point that is pointed to by the d_config member of the drvops(D4) structure. STREAMS modules and STREAMS software drivers (``pseudo'' drivers) that do not provide a config( ) entry point routine must set the d_config member of the drvops structure to NULL.

Open redirection

Open redirection (or ``cloning'') in DDI 8 works differently than in the ODDI and in previous versions of the DDI. DDI 8 drivers cannot use the clone driver; they are responsible for performing their own open redirection. There is no longer a CLONEOPEN flag or even an sflag argument to open(D2). A DDI 8 driver's open entry point routine checks if a particular channel number (the ``clone channel'') was requested. Each driver picks its own clone channel number or numbers. See the open(D2) manual page for details of how to implement open redirection.

Kernel functions

The following STREAMS functions are new to DDI 8:

msgscgth(D3str) Construct a DMA scatter/gather list for a message block.
strioccall(D3str) Invoke a function as the completion of an M_IOCTL operation.
The following DDI 8 functions differ from their equivalents in earlier releases of the DDI and ODDI:

bufcall(D3str) Returns a value of type toid_t, a timeout ID.
esballoc(D3str) The third argument, fr_rtnp, is now of type frtn_t *, the free return data structure.
esbbcall(D3str) Returns a value of type toid_t.
msgpullup(D3str) Replaces pullupmsg which can panic multiprocessor (MP) systems.
put(D3str) Provides an MP-safe, DDI-conforming equivalent of a direct call to the put entry point.
unbufcall(D3str) The argument, id, is now of type toid_t.

When porting ODDI drivers to DDI, additional changes are required to utilize additional DDI functions that are provided:


The qi_qopen and qi_qclose members of qinit, the queue initialization structure, should be set to NULL. The addresses of the open and close routines for a STREAMS driver or module are now picked up from the drvops(D4) structure.

See the stroptions(D4str) manual page for details of how the members of this structure and its options differ in various releases of the DDI and ODDI.

See the copyreq(D4str), copyresp(D4str), and iocblk(D4str) manual pages for details of how the members of these structures differ between the DDI and ODDI.

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005