编写设备驱动程序

ddi_dma_sync() 函数

一个内存对象可能有多个映射,如通过 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 标志的情况执行相应的操作。