一个内存对象可能有多个映射,如通过 DMA 句柄用于 CPU 和用于设备的映射。如果使用任何映射来修改内存对象,则具有多个映射的驱动程序需要调用 ddi_dma_sync(9F)。调用 ddi_dma_sync() 可以确保对内存对象的修改在通过不同映射访问该对象之前完成。如果对对象的任何高速缓存引用现在已过时,ddi_dma_sync() 函数还可以通知该对象的其他映射。此外,ddi_dma_sync() 还会根据需要刷新过时的高速缓存引用或使其无效。
通常,当 DMA 传送完成时,驱动程序必须调用 ddi_dma_sync()。此规则的例外情况是如果使用 ddi_dma_unbind_handle(9F) 取消分配 DMA 资源,则会代表驱动程序隐式执行 ddi_dma_sync()。ddi_dma_sync() 的语法如下:
int ddi_dma_sync(ddi_dma_handle_t handle, off_t off, size_t length, uint_t type);
如果设备的 DMA 引擎要读取对象,则必须通过将 type 设置为 DDI_DMA_SYNC_FORDEV 来同步该设备看到的对象信息。如果设备的 DMA 引擎已写入内存对象并且 CPU 将读取该对象,则必须通过将 type 设置为 DDI_DMA_SYNC_FORCPU 来同步该 CPU 看到的对象信息。
以下示例说明如何为 CPU 同步 DMA 对象:
if (ddi_dma_sync(xsp->handle, 0, length, DDI_DMA_SYNC_FORCPU) == DDI_SUCCESS) { /* the CPU can now access the transferred data */ /* ... */ } else { /* error handling */ }
如果唯一的映射是用于内核的,请使用标志 DDI_DMA_SYNC_FORKERNEL,类似于 ddi_dma_mem_alloc(9F) 所分配的内存中的情况。系统会尝试以比同步 CPU 看到的信息更快的速度来同步内核看到的信息。如果系统无法更快地同步内核看到的信息,则系统将按照如同已设置 DDI_DMA_SYNC_FORCPU 标志的情况执行相应的操作。