UDI driver coding basics

Control block indexes and structures

Control block arrays specify the structure of the control block for each channel operation. There is a one-to-one correspondence between elements in the control block array and the elements of the channel operations vector.

Control blocks passed into a region from another region contain ``per-request data'', whose scope is contained to the channel operation request. The ownership of these per-request data objects is transferred to the target region on the channel; the source region has no access to them once they are transferred. No assumptions about their content can be made on return from the operation.

Control blocks are referred to by an index, and are intialized as part of the uid_init_info per-driver intialization structure (see ``Driver initialization structure''). The indexes and structures for the sample drivers are shown below.

cmos_udi.c sample code (cont.)
    * CB indexes for each of the types of control blocks used.
   #define GIO_BIND_CB_IDX		1
   #define GIO_XFER_CB_IDX		2
   #define GIO_EVENT_CB_IDX	3
   #define BUS_BIND_CB_IDX		4
   #define INTR_ATTACH_CB_IDX	5
   #define INTR_EVENT_CB_IDX	6

/* * -------------------------------------------------------------------- * Control Block init section: * -------------------------------------------------------------------- */ static udi_cb_init_t udi_cmos_cb_init_list[] = { { GIO_BIND_CB_IDX, /* GIO Bind CB */ CMOS_GIO_META, /* from udiprops.txt */ UDI_GIO_BIND_CB_NUM, /* meta cb_num */ GIO_BIND_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, { GIO_XFER_CB_IDX, /* GIO Xfer CB */ CMOS_GIO_META, /* from udiprops.txt */ UDI_GIO_XFER_CB_NUM, /* meta cb_num */ GIO_XFER_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, { GIO_EVENT_CB_IDX, /* GIO Event CB */ CMOS_GIO_META, /* from udiprops.txt */ UDI_GIO_EVENT_CB_NUM, /* meta cb_num */ GIO_EVENT_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, { BUS_BIND_CB_IDX, /* Bridge Bind CB */ CMOS_BRIDGE_META, /* from udiprops.txt */ UDI_BUS_BIND_CB_NUM, /* meta cb_num */ BUS_BIND_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, #if DO_INTERRUPTS { INTR_ATTACH_CB_IDX, /* Interrupt Attach CB */ CMOS_BRIDGE_META, /* from udiprops.txt */ UDI_BUS_INTR_ATTACH_CB_NUM, /* meta cb_num */ INTR_ATTACH_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, { INTR_EVENT_CB_IDX, /* Interrupt Event CB */ CMOS_BRIDGE_META, /* from udiprops.txt */ UDI_BUS_INTR_EVENT_CB_NUM, /* meta cb_num */ INTR_EVENT_SCRATCH, /* scratch requirement */ 0, /* inline size */ NULL /* inline layout */ }, #endif /* DO_INTERRUPTS */ { 0 /* Terminator */ } };

pseudod.c sample code (cont.)
   #define PSEUDO_GIO_XFER_CB_IDX	1	/* Generic xfer  blk for udi_gcb_init */

static udi_ops_init_t pseudo_ops_init_list[] = { { PSEUDO_GIO_INTERFACE, PSEUDO_GIO_META, /* meta index */ UDI_GIO_PROVIDER_OPS_NUM, /* meta ops num */ 0, /* chan context size */ (udi_ops_vector_t *) & pseudo_gio_provider_ops, /* ops vector */ pseudo_default_op_flags }, { PSEUDO_BUS_INTERFACE, PSEUDO_BUS_META, /* Bus meta index [from udiprops.txt] */ UDI_BUS_DEVICE_OPS_NUM, 0, /* channel context size */ (udi_ops_vector_t *) & pseudo_bus_device_ops, pseudo_default_op_flags }, { 0} };

All control blocks are initialized using an array of udi_cb_init_t structures, using the control block indexes as indexes into the array.

   typedef struct {
   	udi_index_t		cb_idx ;
   	udi_index_t		meta_idx ;
   	udi_index_t		meta_cb_num ;
   	udi_size_t		scratch_requirement ;
   	udi_size_t		inline_size ;
   	const udi_layout_t	*inline_layout ;
   } udi_cb_init_t ;

For the sample drivers, the cb_idx definitions are shown above. The meta_idx members are populated using defined constants from the build instructions section of udiprops.txt (see ``Build instructions'').

The type of the control block is specified by the meta_cb_num element, a ``control block group number'' from the UDI Specifications. The meta_idx and meta_cb_num, taken together, specify a control block structure type defined for a particular metalanguage. For example, in the udi_cmos sample, a meta_idx of CMOS_GIO_META points to the GIO metalanguage defined in the Core Specification, and a meta_cb_num of UDI_GIO_XFER_CB_NUM specifies the control block for GIO transfer operations, udi_gio_xfer_cb_t(3udi). This is used later in the driver's child channel operations (see ``udi_cmos child channel operations'').

Scratch space requirements for the udi_cmos driver are given using the constants defined earlier (see ``Scratch space, offsets, and requirements''). The pseudod driver uses no scratch space, so gives its requirements as zero.

The next two elements of the control block intialization structure, inline_size and inline_layout, may contain size and layout information for ``inline data'' in the control block. This is data particular to a channel operation that is local to the operation (called ``per-request data'' in ``Control block indexes and structures'').

For example, in the pseudod sample driver, the first control block definition above specifies inline data size and layout information for the udi_gio_xfer_cb_t control block type specified in the control block initialization structure udi_cb_init_t. The layout is specified using the udi_layout_t type prior to the control block intialization structure definition in the source, The layout uses UDI fundamental types, and is specific to the channel operation. See ``Channel operation data layouts''.

Next topic: Programmed I/O (PIO)
Previous topic: Scratch space, offsets, and requirements

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