udi_scgth_t(3udi)


I/O Bus scatter/gather structure

SYNOPSIS

#include <udi.h>

typedef struct {

	udi_ubit32_t block_busaddr;

	udi_ubit32_t block_length;

} udi_scgth_element_32_t;
 
typedef struct {

	udi_busaddr64_t block_busaddr;

	udi_ubit32_t block_length;

	udi_ubit32_t el_reserved;

} udi_scgth_element_64_t;
 
/* Extension Flag */
 
#define  UDI_SCGTH_EXT
 
0x80000000
 
typedef struct {

	udi_ubit16_t scgth_num_elements;

	udi_ubit8_t scgth_format;

	udi_boolean_t scgth_must_swap;

	union {

	    udi_scgth_element_32_t *el32p;

	    udi_scgth_element_64_t *el64p;

	} scgth_elements;

	union {

	    udi_scgth_element_32_t el32;

	    udi_scgth_element_64_t el64;

	} scgth_first_segment;

} udi_scgth_t;
 
/* Values for scgth_format */
 
#define UDI_SCGTH_32 (1U<<0) #define UDI_SCGTH_64 (1U<<1) #define UDI_SCGTH_DMA_MAPPED (1U<<6) #define UDI_SCGTH_DRIVER_MAPPED (1U<<7)

MEMBERS block_busaddr is the I/O card-relative bus address of a contiguous block of data bytes (if UDI_SCGTH_EXT bit is cleared), or an extension array of udi_scgth_element_t elements (if UDI_SCGTH_EXT is set). These blocks are contiguous from the I/O card's perspective. See the DESCRIPTION below for comments on device endianness.

block_length is the length of the related block. If this is an extension element (the UDI_SCGTH_EXT bit is set) then this is the size in bytes of the next scatter/gather block, including the indirect element in that block, if present. If this is not an extension element then this is the size in bytes of the DMA data associated with this block_busaddr. In the UDI_SCGTH_32 format, the UDI_SCGTH_EXT bit is part of this field.

el_reserved includes the UDI_SCGTH_EXT bit in the UDI_SCGTH_64 format. Other bits are unused.

UDI_SCGTH_EXT is a mask value, to be applied to the block_length field of a udi_scgth_element_32_t or the el_reserved field of a udi_scgth_element_64_t. If this bit is set, then the scatter/gather element is an indirect reference to a possibly physically-discontiguous continuation of the scatter/gather list.

scgth_num_elements gives the number of direct udi_scgth_element_t elements included in the entire scatter/gather list (indirect elements are not included, but elements from all segments are included). This may be used to estimate I/O driver control resources.

scgth_format indicates the format of the scatter/gather elements. Exactly one of the following flags will be set in scgth_format, corresponding to the 32-bit and 64-bit scatter/gather formats, respectively:
UDI_SCGTH_32
UDI_SCGTH_64

In addition, the UDI_SCGTH_DMA_MAPPED flag will be set if the scatter/gather list is "DMA-mapped", meaning that the list elements themselves are made readable from the adapter via DMA and are in an endianness appropriate for access by the device (as indicated by the UDI_DMA_SCGTH_ENDIANNESS constraints attribute). The driver must ensure that its DMA device does not write to the scatter/gather list memory.

The UDI_SCGTH_DRIVER_MAPPED flag will be set if the scatter/gather list is (also) "driver-mapped", meaning that the list elements are readable from the driver via the el32p or el64p pointer. Otherwise, these pointers are unused and their value is unspecified. The list elements will be in the driver's endianness if and only if driver-mapped and not DMA-mapped.

The scgth_format value used for a scatter/gather list is determined by the value of the UDI_DMA_SCGTH_FORMAT constraints attribute used to create the scatter/gather list.

scgth_must_swap is a flag indicating that the driver must swap endianness when accessing driver-mapped list elements via el32p or el64p. This flag will always be FALSE if the scatter/gather list is not DMA-mapped. If not driver-mapped, the value of the flag is unspecified and must not be used. When the scatter/gather list is both DMA-mapped and driver-mapped, the driver must check this flag; it must not assume it knows whether or not to swap, based on its specified UDI_DMA_SCGTH_ENDIANNESS, since interposed bus bridges may change the endianness.

See Section 22.2, "Endianness Management," on page 22-2 of the UDI Core Specification for details on how to construct C structure definitions for proper endianness handling, and the endian swapping utilities that are available.

el32p, el64p are members of the scgth_elements union. One of these, depending on the value of scgth_format, will be set to be a pointer to the scatter/gather list in the driver's address space if UDI_SCGTH_DRIVER_MAPPED is set in scgth_format.

scgth_first_segment is only used for DMA-mapped scatter/gather lists. Depending on the value of scgth_format, el32 or el64 contains the I/O-card relative address of the beginning of the scatter/gather list and the length in bytes of the first segment in this list. scgth_first_segment is similar to an IEEE-1212.1 indirect element, except that the UDI_SCGTH_EXT bit is never set.

DESCRIPTION The udi_scgth_t structure provides a way to access the block vector array segment(s) that describe the memory addresses of a DMA-mapped data buffer or shared control structure memory. Scatter/gather lists are built by the environment as a result of calls to udi_dma_buf_map or udi_dma_mem_alloc.

Scatter/gather lists are presented in either 32-bit or 64-bit format, as requested by the driver through its DMA constraints. The format used is reported back to the driver through scgth_format. (See UDI_DMA_SCGTH_FORMAT on page page 3-18 in udi_dma_constraints_attr_t.)

Depending on the value of the UDI_DMA_SCGTH_FORMAT constraints attribute, the scatter/gather elements may be DMA-mapped, driver-mapped, or both. The driver chooses the appropriate visibility depending on how closely its device's scatter/gather format resembles the UDI scatter/gather list format (which is based on IEEE-1212.1). If they are identical, the driver should choose UDI_SCGTH_DMA_MAPPED and let its device access the scatter/gather list directly. If the formats are similar, but not identical, the driver may choose to use both UDI_SCGTH_DMA_MAPPED and UDI_SCGTH_DRIVER_MAPPED and modify the scatter/gather elements in place (being careful to observe scgth_must_swap if set) before having the device access the list. Otherwise, the driver should use just UDI_SCGTH_DRIVER_MAPPED and use separately allocated DMA-able memory or PIO to build a scatter/gather list in the appropriate format, based on the values it reads from the scgth_elements array.

If DMA-mapped, the memory for the scatter/gather segments themselves will conform to the DMA constraints related to scatter-gatter memory, and the associated udi_scgth_t structure will contain an indirect reference to the first element of the scatter/gather list in scgth_first_segment. The members of the el32 or el64 element within this union are in the driver's endianness. The block_busaddr member contains the I/O card-relative address of the beginning of the scatter/gather list, and the block_length member contains the length of the first segment of this list, including an indirect element, if any exists.

If not DMA-mapped, the scgth_first_segment field of udi_scgth_t is not valid, and the scatter/gather list will not contain extension elements (UDI_SCGTH_EXT); the entire list is provided in a single block vector segment.

The environment's use of the IEEE-1212.1 structures is such that all the udi_scgth_element_t elements in a block vector segment are used before chaining to the next segment. Therefore, the driver can use the length of the block vector segment to determine where the next indirect udi_scgth_element_t pair is, if any. Therefore, it is not necessary for the driver to check for UDI_SCGTH_EXT for other elements in the segment. Note, though, that the last segment may contain fewer elements than covered by the length of the segment; the total number of direct elements (scgth_num_elements) or the total size of the mapped memory must be used to determine that the end of the list has been reached.

warnings The udi_scgth_t type is not transferable between regions.


UDI Physical I/O Specification Contents