Data Structures
The d_map_init service and the d_map_init_ext service return a d_handle_t structure to the caller upon a successful completion. Only the d_map_init service and the d_map_init_ext service are the exported kernel services.
d_handle {
uint id; /* identifier for this device */
uint flags; /* device capabilities */
#ifdef __64BIT_KERNEL
/* pointer to d_map_page routine */
int (*d_map_page)(d_handle_t,int,caddr_t, ulong *, struct xmem
*);
/* pointer to d_unmap_page routine */
void (*d_unmap_page)(d_handle_t, ulong *);
/* pointer to d_map_list routine */
int (*d_map_list)(d_handle_t, int, int, dio_t, dio_t);
/* pointer to d_unmap_list routine */
void (*d_unmap_list)(d_handle_t, dio_t);
/* pointer to d_map_slave routine */
int (*d_map_slave)(d_handle_t, int, int, dio_t, uint);
/* pointer to d_unmap_slave routine */
int (*d_unmap_slave)(d_handle_t);
/* pointer to d_map_disable routine */
int (*d_map_disable)(d_handle_t);
/* pointer to d_map_enable routine */
int (*d_map_enable)(d_handle_t);
/* pointer to d_map_clear routine */
void (*d_map_clear)(d_handle_t);
/* pointer to d_sync_mem routine */
int (*d_sync_mem)(d_handle_t, dio_t);
#else
int (*d_map_page)(); /* pointer to d_map_page routine */
void (*d_unmap_page)(); /* pointer to d_unmap_page routine */
int (*d_map_list)(); /* pointer to d_map_list routine */
void (*d_unmap_list)(); /* pointer to d_unmap_list routine */
int (*d_map_slave)(); /* pointer to d_map_slave routine */
int (*d_unmap_slave)(); /* pointer to d_unmap_slave routine */
int (*d_map_disable)(); /* pointer to d_map_disable routine */
int (*d_map_enable)(); /* pointer to d_map_enable routine */
void (*d_map_clear)(); /* pointer to d_map_clear routine */
int (*d_sync_mem)(); /* pointer to d_sync_mem routine */
#endif
int bid; /* bus id passed to d_map_init or d_map_init_ext*/
void *bus_sys_xlate_ptr; /* pointer to dma bus to system
translation information */
uint reserved1; /* padding */
uint reserved2; /* padding */
uint reserved3; /* padding */
};
The following dio and d_iovec structures are used to define the scatter and gather lists used by the d_map_list, d_unmap_list, and d_map_slave services (see the sys/dma.h system file).
struct dio {
int32long64_t total_iovecs; /* total available iovec entries */
int32long64_t used_iovecs; /* number of used iovecs */
int32long64_t bytes_done; /* count of bytes processed */
int32long64_t resid_iov; /* number of iovec that couldn't be */
/* fully mapped due to NORES,DIOFULL*/
/* vec =&dvec [resid_iov] */
struct d_iovec *dvec; /* pointer to list of d_iovecs */
};
struct d_iovec {
caddr_t iov_base; /* base memory address */
int32long64_t iov_len; /* length of transfer for this area */
struct xmem *xmp; /* cross memory pointer for this address*/
};
The following dio_64 and d_iovec_64 structures are used to define the scatter and gather lists used by the d_map_list and d_unmap_list services when the DMA_ENABLE_64 flag is set on the d_map_init call or the d_map_init_ext call. These are not used under the 64-bit kernel and kernel extension environment because the dio and d_iovec data structures are naturally 64-bit capable in that environment. (For more information, see the sys/dma.h system file.)
struct dio_64 {
int total_iovecs; /* total available iovec entries */
int used_iovecs; /* number of used iovecs */
int bytes_done; /* count of bytes processed */
int resid_iov; /* number of iovec that couldn't be */
/* fully mapped due to NORES,DIOFULL*/
/* vec = &dvec [resid_iov] */
struct d_iovec_64 *dvec; /* pointer to list of d_iovecs */
};
struct d_iovec_64 {
unsigned long long iov_base; /* base memory address */
int iov_len; /* length of transfer for this area */
struct xmem *xmp; /* cross memory pointer for this address*/
}
The following macros are provided in sys/dma.h for device drivers in order to call the DMA kernel services cleanly:
#define D_MAP_INIT(bid, flags, bus_flags, channel) \
d_map_init(bid, flags, bus_flags, channel)
#define D_MAP_INIT_EXT(dma_input, info_size, handle_ptr) \
d_map_init_ext(dma_input, info_size, handle_ptr)
#define D_MAP_CLEAR(handle) (handle->d_map_clear)(handle)
#define D_MAP_PAGE(handle, flags, baddr, busaddr, xmp) \
(handle->d_map_page)(handle,flags, baddr, busaddr, xmp)
#define D_UNMAP_PAGE(handle, bus_addr) \
if (handle->d_unmap_page != NULL) (handle->d_unmap_page)(handle, bus_addr)
#define D_MAP_LIST(handle, flags, minxfer, virt_list, bus_list) \
(handle->d_map_list)(handle, flags, minxfer, virt_list,bus_list)
#define D_UNMAP_LIST(handle, bus_list) \
if (handle->d_unmap_list != NULL)(handle->d_unmap_list)(handle, bus_list)
#define D_MAP_SLAVE(handle, flags, minxfer, vlist, chan_flags) \
(handle->d_map_slave)(handle, flags, minxfer, vlist, chan_flags)
#define D_UNMAP_SLAVE(handle) \
(handle->d_unmap_slave != NULL) ? \
(handle->d_unmap_slave)(handle) : DMA_SUCC
#define D_MAP_DISABLE(handle) (handle->d_map_disable)(handle)
#define D_MAP_ENABLE(handle) (handle->d_map_enable)(handle)
#define D_SYNC_MEM(handle, bus_list) \
(handle->d_sync_mem != NULL) ? \
(handle->d_sync_mem)(handle, bus_list) : DMA_SUCC
#define D_MAP_ATTR(handle, cmd, attr, attr_size) \
(handle->d_map_attr)(handle, cmd, attr, attr_size)