|
|
udi_layout_t(3udi)
Data layout specifier
#include <udi.h>typedef const udi_ubit8_t udi_layout_t; /* Specific-Length Layout Type Codes */#define UDI_DL_UBIT8_T 1 #define UDI_DL_SBIT8_T 2 #define UDI_DL_UBIT16_T 3 #define UDI_DL_SBIT16_T 4 #define UDI_DL_UBIT32_T 5 #define UDI_DL_SBIT32_T 6 #define UDI_DL_BOOLEAN_T 7 #define UDI_DL_STATUS_T 8/* Abstract Element Layout Type Codes */#define UDI_DL_INDEX_T 20/* Opaque Handle Element Layout Type Codes */#define UDI_DL_CHANNEL_T 30 #define UDI_DL_ORIGIN_T 32/* Indirect Element Layout Type Codes */#define UDI_DL_BUF 40 #define UDI_DL_CB 41 #define UDI_DL_INLINE_UNTYPED 42 #define UDI_DL_INLINE_DRIVER_TYPED 43 #define UDI_DL_MOVABLE_UNTYPED 44/* Nested Element Layout Type Codes */#define UDI_DL_INLINE_TYPED 50 #define UDI_DL_MOVABLE_TYPED 51 #define UDI_DL_ARRAY 52 #define UDI_DL_END 0description A data layout specifier consists of an array of one or more udi_layout_t layout elements. Each element contains a type code indicating one of the UDI data types that can be passed into a channel operation, either as a field in the control block or as an additional parameter. Each successive element of the array represents successive offsets within the described structure, with padding automatically inserted for alignment purposes as if the specified data types had appeared in a C struct declaration.
Since channel operations are based on strongly typed function calls, the environment usually has sufficient information to handle data transformations such as endian conversions when channel operations cross between domains of differing data formats. However, there are some cases where one or more parameters to a channel operation call are not strongly typed, but are simply void * pointers to chunks of memory. Such pointers must point either to movable memory (allocated by udi_mem_alloc with the UDI_MEM_MOVABLE flag set) or to inline memory permanently associated with a control block when it was allocated.
If such untyped memory is also unstructured-that is, it is to be treated as an array of bytes-then no data transformations need be performed. If the memory is structured, however, drivers must inform the environment of that structure, since it cannot be determined a priori from the channel operation definition. In that case, the driver supplies a data layout specifier as a parameter to the "cb_init" function with which the operation is associated.
Layout element type values for udi_layout_t are defined with mnemonic constants as shown in the following table:
Table 9-4 Abstract Element Type Codes Element Type Code Value Corresponding Data Type UDI_DL_INDEX_T udi_index_t For all nested element types, the layout elements following the nested type, up until the matching UDI_DL_END, describe the structure of that element. For driver-type inline structures, indicated by UDI_DL_INLINE_DRIVER_TYPED, the driver-provided layout array is logically inserted as a nested element.
Since nested objects might be variable length arrays of structures, the layout elements for a nested object may need to be repeated to cover the whole nested object, as if the nested layout were describing the structure of one element of such an array. Partial repeats are not allowed; the object must be covered by zero or more complete repeats of the nested layout.
The udi_layout_t array must end with a UDI_DL_END element; the first UDI_DL_END not used to match a nested element type is interpreted as the end of the array.
Note - The various INLINE element types and UDI_DL_CB must not be used as part of the layout description for inline memory contents, since nested inline structures are not supported. They are only legal for control block visible layouts. At most one UDI_DL_CB element may be used within a single layout array.
The UDI_DL_BUF type is used for a pointer to a udi_buf_t buffer. It is followed by three unsigned bytes providing further details. These are used to describe related control block fields that affect the way the buffer and its data are handled during domain crossings and during abrupt driver termination ("region kill"). The meaning of each of these bytes is listed below.
byte 0 designates the control block field, if any, that holds a flag or type code that can be used to distinguish between buffers flowing in the "forward" direction (i.e. carrying significant data-typically a "write" request or a "read" acknowledgement) and those flowing in the "reverse" direction (i.e. carrying data that does not need to be preserved-typically a "read" request or a "write" acknowledgement). This field is referred to as the preserve flag for purposes of this layout element specifier. The value in byte 0 is used as a zero-based index into the layout specifier for the control block to which this UDI_DL_BUF applies; this selects the layout element that corresponds to the preserve flag.
byte 1 supplies a mask value to apply to the low order byte of the preserve flag value.
byte 2 supplies a match value to compare with the masked preserve flag value. If they compare equal, the environment must preserve any previously preserved data content and tags in the buffer, up to the buffer's current buf_size, when the data is transferred via channel operation to the new region. If the masked preserve flag does not equal the match value, then all of the buffer's contents in the new region are unspecified, and buffer tags are removed, but the buf_size value is unchanged.
If the above criteria indicate that buffer data is to be preserved, then environments that might use "region kill" must track this buffer and return it to the sending region (by failing the request with a status of UDI_STAT_TERMINATED) if the receiving region is abruptly terminated while still holding this buffer.