typedef struct ddi_dma_attr { uint_t dma_attr_version; /* version number */ uint64_t dma_attr_addr_lo; /* low DMA address range */ uint64_t dma_attr_addr_hi; /* high DMA address range */ uint64_t dma_attr_count_max; /* DMA counter register */ uint64_t dma_attr_align; /* DMA address alignment */ uint_t dma_attr_burstsizes; /* DMA burstsizes */ uint32_t dma_attr_minxfer; /* min effective DMA size */ uint64_t dma_attr_maxxfer; /* max DMA xfer size */ uint64_t dma_attr_seg; /* segment boundary */ int dma_attr_sgllen; /* s/g length */ uint32_t dma_attr_granular; /* granularity of device */ uint_t dma_attr_flags; /* Bus specific DMA flags */ } ddi_dma_attr_t;
其中:
特性结构的版本号。dma_attr_version 应设置为 DMA_ATTR_V0。
DMA 引擎可以访问的最低总线地址。
DMA 引擎可以访问的最高总线地址。
指定 DMA 引擎可在一个 cookie 中处理的最大传送计数。该限制表示为最大计数减 1。此计数用作位掩码,因此计数也必须比 2 的幂小 1。
指定通过 ddi_dma_mem_alloc(9F) 分配内存时的对齐要求。例如,以页边界对齐。dma_attr_align 字段仅在分配内存时使用。在绑定操作过程中,将省略此字段。对于绑定操作,驱动程序必须确保缓冲区已正确对齐。
指定设备支持的突发流量大小。突发流量大小是指设备在放弃总线之前可以传输的数据量。此成员是突发流量大小的二进制编码,这些大小是 2 的幂次方。例如,如果设备能够执行 1 字节、2 字节、4 字节和 16 字节突发传输,则应将此字段设置为 0x17。系统还会使用此字段来确定对齐限制。
设备可以执行的最小有效传送大小。此大小还会影响对齐和填充的限制。
描述 DMA 引擎在一个 I/O 命令中可以容纳的最大字节数。此限制仅在 dma_attr_maxxfer 小于 (dma_attr_count_max + 1) * dma_attr_sgllen 时才会有意义。
DMA 引擎的地址寄存器的上限。当地址寄存器的高 8 位为包含段号的锁存器时,通常会使用 dma_attr_seg 。低 24 位用于寻址段。在此情况下,dma_attr_seg 会设置为 0xFFFFFF,这可以防止系统在为对象分配资源时跨越 24 位段边界。
指定分散/集中列表中的最大项数。dma_attr_sgllen 是 DMA 引擎在对设备的一个 I/O 请求中可以使用的 cookie 数。如果 DMA 引擎不包含任何分散/集中列表,则此字段应设置为 1。
此字段用于提供设备 DMA 传送能力的粒度(以字节为单位)。指定海量存储设备的扇区大小即是关于如何使用该值的一个例子。如果绑定操作需要部分映射,则可使用此字段确保 DMA 窗口中的 cookie 大小之和为粒度的整数倍。但是,如果设备没有分散/集中功能,则 DDI 无法确保粒度。对于此情况,dma_attr_granular 字段的值应为 1。
此字段可以设置为 DDI_DMA_FORCE_PHYSICAL,这表示如果系统同时支持物理 I/O 地址和虚拟 I/O 地址,则系统应返回物理 I/O 地址而非虚拟 I/O 地址。如果系统不支持物理 DMA,则 ddi_dma_alloc_handle(9F) 的返回值为 DDI_DMA_BADATTR。在此情况下,驱动程序必须清除 DDI_DMA_FORCE_PHYSICAL 并重试该操作。