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.

All other DMA kernel services are called through the function pointers in the d_handle_t structure (see the sys/dma.h system file).

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)