|
|
udi_dma_mem_alloc(3udi)
Allocate shared control structure memory
#include <udi.h>void udi_dma_mem_alloc ( udi_dma_mem_alloc_call_t *callback, udi_cb_t *gcb, udi_dma_constraints_t constraints, udi_ubit8_t flags, udi_ubit16_t nelements, udi_size_t element_size, udi_size_t max_gap ); typedef void udi_dma_mem_alloc_call_t ( udi_cb_t *gcb, udi_dma_handle_t new_dma_handle, void *mem_ptr, udi_size_t actual_gap, udi_boolean_t single_element, udi_scgth_t *scgth, udi_boolean_t must_swap ); /* Values for flags */#define UDI_DMA_OUT (1U<<2) #define UDI_DMA_IN (1U<<3) #define UDI_DMA_BIG_ENDIAN (1U<<5) #define UDI_DMA_LITTLE_ENDIAN (1U<<6) #define UDI_DMA_NEVERSWAP (1U<<7)ARGUMENTS callback, gcb are standard arguments described in the "Asynchronous Service Calls" section of "Standard Calling Sequences" in the UDI Core Specification.
constraints is a UDI constraints handle that defines the memory constraints of the DMA engine that will be accessing the allocated memory.
flags is a bitmask of flags, that control the operation of this function.
These flags must include one or both of the following direction flags, which indicate the direction(s) of DMA transfers that may be used:
UDI_DMA_IN - transfers from device to memory.
UDI_DMA_OUT - transfers from memory to device.
The flags must also include exactly one of:
UDI_DMA_BIG_ENDIAN - access data in big endian format.
UDI_DMA_LITTLE_ENDIAN - access data in little endian format.
UDI_DMA_NEVERSWAP - access data with no byte swapping (appropriate for character data).
Finally, flags may optionally include UDI_MEM_NOZERO.
nelements indicates the number of memory elements that are to be allocated.
element_size indicates the size of each element to be allocated.
max_gap indicates the maximum number of bytes that may separate each element from the last byte of the preceeding element to the first byte of the next element. A driver will typically set this to indicate how far apart the elements may be for the device to properly address them; a max_gap of zero indicates that the elements must be adjacent in memory.
new_dma_handle is an opaque handle to the newly allocated DMA object.
mem_ptr is a driver-mapped pointer to the allocated DMA-able memory.
actual_gap indicates the actual number of bytes that separate each control structure in memory. This value will be equal to or less than the requested max_gap value unless the environment could not satisfy the requested parameters, in which case single_element will be TRUE and the actual_gap argument must be ignored. This argument must also be ignored if nelements is 1.
single_element is a flag indicating whether all elements were allocated or whether only a single element was allocated. This will return true when the allocation specified by the arguments, including the specified constraints, cannot be satisfied; in this case only one element is allocated and returned. This argument must be ignored if nelements is 1.
scgth is a pointer to a DMA scatter/gather structure for the newly allocated memory.
must_swap is a flag indicating that the driver must swap endianness when it accesses the DMA-able memory via mem_ptr. This will be computed by the environment as a function of the driver's endianness, the device endianness specified in flags, and any interceding bus bridges. Because bridges may introduce additional endianness changes, drivers must always check this flag rather than assuming swapping or not swapping.
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.
DESCRIPTION Allocates control structure memory that is to be shared between a UDI device driver and its corresponding DMA device. This memory will conform to the requirements expressed in constraints. The device accesses the memory via DMA. The driver accesses the memory using the mem_ptr pointer, and must handle endian conversions if so indicated by the must_swap flag.
If the driver will be using the memory for multiple separate control structures, the nelement and element_size arguments should be used to describe the individual control structures. The system will adjust the allocation to ensure that each control structure: (1) starts on an appropriate alignment boundary, (2) does not share cache lines with other control structures, and (3) is physically contiguous. This adjustment is indicated by the actual_gap value returned on the callback which indicates the number of additional bytes allocated between each control structure to satisfy the individual alignment requirements. This gap will not exceed the device's capabilities as indicated by the max_gap argument; if the required gap size would exceed this value, then only a single element is allocated as indicated by the single_element argument.
Each gap represents actual allocated memory bytes; these bytes appear in both the virtual and the DMA-mapped address ranges and the driver should make appropriate considerations for accessing each element. There is no gap following the last element allocated.
The newly allocated memory will be zeroed unless UDI_MEM_NOZERO is set, in which case the initial values are unspecified.
The newly allocated memory will be aligned on the most restrictive alignment of the platform's natural alignments for long and pointer data types, allowing the allocated memory to be directly accessed as C structures.
At the time of the callback, the memory is mapped for DMA access by the device. The DMA mapped memory remains allocated and mapped until new_dma_handle is freed by a call to udi_dma_free or udi_dma_mem_to_buf, at which point the memory will be automatically unmapped and deallocated. udi_dma_mem_to_buf allows a range of data from the control structure memory to be placed into a UDI buffer.
Note - Unlike udi_dma_buf_map, udi_dma_mem_alloc will always produce a complete mapping.
This call is typically used for allocating memory that is contiguous from the device's perspective, but some devices may support discontiguous control memory. Whether or not contiguous device addresses are used is under control of the UDI_DMA_SCGTH_MAX_ELEMENTS property of the constraints handle, but the memory will always be virtually contiguous when accessed through the mem_ptr pointer. See udi_dma_constraints_attr_t (DMA) for details on DMA constraints.
Note - In order to use the byte-by-byte structure layout technique for mixed endianness access to shared control structure memory, and the utility macros defined in Section 22.2, "Endianness Management," on page 22-2 of the UDI Core Specification, the driver must declare two versions of the relevant structure(s), type-casting appropriately, and using the version that matches the device's endianness if must_swap is FALSE, or the "anti-endian" version if must_swap is TRUE.
REFERENCES udi_dma_limits, udi_dma_constraints_attr_t, udi_dma_prepare, udi_dma_buf_map, udi_dma_free, udi_dma_sync, udi_dma_mem_barrier, udi_scgth_t, udi_dma_mem_to_buf