DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
TOC PREV NEXT INDEX

Calling Sequence and Naming Conventions

7

7.1 Overview

This chapter defines naming and calling conventions that apply to UDI environment interfaces in general. All calls of certain general types have common properties.

This chapter also defines conventions for metalanguage-specific interfaces. Some of these conventions are specified as strict requirements for all metalanguages; others are simply recommendations that may be overridden by metalanguage designers.

Generally, conventions covering required function parameters and types are strict requirements, while conventions covering function, parameter, and macro naming are recommendations. Metalanguage designers are free to use different naming conventions as long as the interface requirements defined below are met and the resulting names would be considered unique within the UDI interface namespace (at least as unique as the recommended conventions described in this chapter).

There are two function call categories to which these conventions apply: channel operations and asynchronous service calls. For more details on function call categorization see Section 4.8, "Function Call Classifications".

In addition, conventions apply to the naming of metalanguage-specific channel ops vector types and control block group numbers.

7.2 Channel Operations

Channel operations are invoked by a driver or by the environment and result in a procedure call to an operation entry point in another region. The calling sequence for the invocation of a channel operation (caller-side interface) is identical to the calling sequence for the corresponding entry point (callee-side interface). Caller-side functions have specific names, such as udi_gio_xfer_req. Callee-side functions have the same prototype as the caller-side equivalent, but will have names private to the driver, such as my_gio_xfer_req, and should be static symbols.

7.2.1 Channel Operation Invocations

Channel operations are metalanguage-specific. The invocation calls have declarations with the following form:

void <<meta>>_<<op>> (
 
	<<meta>>_<<cbtype>>_cb_t *cb,
 
	...<<call-dependent parms>>... );
 

where:

<<meta>>	is a distinct prefix identifying the metalanguage, usually beginning with the 
prefix, "udi_".
 
<<op>>	identifies the particular channel operation within the metalanguage.
 
<<cbtype>>	identifies the particular control block type within the metalanguage.
 
cb	is a pointer to the semi-opaque metalanguage-specific control block, of 
type <<meta>>_<<cbtype>>_cb_t, for this operation.
 
<<call-dependent parms>>	are the zero or more metalanguage-dependent parameters for this particular 
channel operation.
 

Channel operation invocation calls are required to begin with an argument with the semantics described above for cb. The name of this argument and the naming of <<meta>>, <<op>>, and <<cbtype>> are up to the metalanguage designer, but the above naming conventions are recommended.

The target channel over which to send the operation is determined by the value of cb->gcb.channel. The particular channel type to use for the operation is specified in the TARGET CHANNEL section of the reference page defining the operation.

7.2.2 Channel Operation Entry Points

The corresponding operation entry point in the target driver can have any name, but by convention has the same name as the invocation call with the initial "udi" prefix replaced by a driver-specific prefix, "ddd." In any case, the arguments will be as shown in the following declaration:

static void ddd_<<meta>>_<<op>> (

	<<meta>>_<<cbtype>>_cb_t *cb,

	...<<call-dependent parms>>... );
 

This is the same as the calling sequence for the corresponding channel operation invocation.

For example, one driver may call:

udi_intr_event_ind(intr_event_cb, flags);
 

This would result in an invocation of the target driver's entry point routine for the target channel for this operation:

udi_intr_event_ind_op_t my_intr_event_ind;
 
	:
 
my_intr_event_ind(intr_event_cb, flags);
 

For convenience in the declaration of ops vector types and operation entry point forward declarations, a standard typedef shall be defined by the metalanguage header files for each operation type, in the form:

typedef void <<meta>>_<<op>>_op_t (

	<<meta>>_<<cbtype>>_cb_t *cb,

	...<<call-dependent parms>>... );
 

7.3 Asynchronous Service Calls

Asynchronous service calls are calls to the environment in which the result may not be immediately available and is therefore supplied via a callback routine rather than as a direct return value of the service call itself (see Section 4.8.1.2). These types of calls are a core mechanism of the non-blocking UDI model of execution.

7.3.1 Asynchronous Service Call Invocations

Asynchronous service calls all have declarations with the following form:

void udi_<<category>>_<<service>> (

	udi_<<category>>_<<service>>_call_t *callback,

	udi_cb_t *gcb,

	...<<call-dependent parms>>... );
 

where:

<<category>>	is a distinct prefix identifying the service category, such as "buf" for 
buffer management.
 
<<service>>	identifies the particular service within the category.
 
callback	is a pointer to the driver's callback routine, of type 
udi_<<category>>_<<service>>_call_t.
 
gcb	is a pointer to a generic control block.
 
<<call-dependent parms>>	are the zero or more specific additional parameters for this service call.
 

7.3.2 Associated Callback Functions

Callback functions are called upon completion of the service request. The declaration for each callback type appears on the reference page along with the associated service call, in the following form:

typedef void udi_<<category>>_<<service>>_call_t (

	udi_cb_t *gcb,

	...<<callback-dependent parms>>... );
 

where:

<<callback-dependent parms>>	 are zero or more additional parameters specific to this callback type.
 

In the driver's code, the callback routine would appear as:

static void ddd_<<category>>_<<service>>_callback (

	udi_cb_t *gcb,

	...<<callback-dependent parms>>... )

{

	...

}
 

For example, a driver may call the environment as follows to obtain a new control block:

udi_cb_alloc(&my_cb_alloc_callback, gcb, my_cb_idx, chan);
 

which will result in calling the following callback when the allocation is complete:

udi_cb_alloc_call_t my_cb_alloc_callback;
 
	:
 
my_cb_alloc_callback(gcb, new_cb);
 

7.3.3 Control Block Type Conversion

Although the asynchronous service calls are defined to use a "generic control block", the driver may use any control block for this purpose because all control blocks are a superset of the generic control block definition. The control block passed to a driver via a channel operation entry point is typically used for all asynchronous service calls and the subsequent channel operation made while processing that operation.

The UDI_GCB() macro (defined on page 11-11) is provided for convenience in converting a specific control block pointer to a generic control block pointer, in order to pass it to a service call. Using this macro, a typical asynchronous service call invocation becomes:

udi_<<category>>_<<service>>(callback, UDI_GCB(cb), ...);
 

The UDI_MCB() macro (defined on page 11-12) is provided for convenience in converting a generic control block pointer back to a specific control block type. Using this macro, a callback routine typically begins with:

<<meta>>_<<cbtype>>_cb_t *cb =

		UDI_MCB(gcb, <<meta>>_<<cbtype>>_cb_t);
 

7.4 Channel Operations Vectors

The channel operations vector structure ("ops vector") used with each type of channel endpoint is defined in each metalanguage. These structures generally have declarations of the following form:1

typedef struct {
 
	udi_channel_event_ind_op_t *channel_event_ind_op;
 
	<<meta>>_<<op_1>>_op_t *<<op_1>>_op;
 
	...
 
	<<meta>>_<<op_N>>_op_t *<<op_N>>_op;
 
} <<meta>>_<<role>>_ops_t;
 

where:

<<meta>> and <<role>>	are defined as above in the "ops_init" calling sequence.
 
<<op_1>>..<<op_N>>	identifies one or more channel operation entry point types that belong to 
this ops vector. These have the callee-side calling sequences defined in 
Section 7.2.2, "Channel Operation Entry Points".
 

Each entry in the ops vector is the driver's entry point for the corresponding channel operation.

Associated with each ops vector definition is a metalanguage-defined number that identifies this ops vector type with respect to others in the same metalanguage. Metalanguages must define both the numeric value and a mnemonic to use for that value. The mnemonic is typically named:

<<meta>>_<<role>>_OPS_NUM
 

where:

<<meta>> and <<role>>	are upper-case versions of those used in the above type definition.
 

7.5 Control Block Groups

Associated with each control block group is a metalanguage-defined number that identifies this control block group with respect to others in the same metalanguage. Metalanguages must define both the numeric value and a mnemonic to use for that value. The mnemonic is typically named:

<<meta>>_<<cbgroup>>_CB_NUM
 

1The Management Metalanguage deviates from this form in that it doesn't have a channel_event_ind_op as the first member; all other metalanguages must have the first member of type udi_channel_event_ind_op_t as shown here.


TOC PREV NEXT INDEX