在ARM处理器中,DMA引擎的实现常常存在问题,这可能会导致PCIe DMA失败。为了解决这个问题,可以考虑以下方法:
以下是在驱动中使用bounce buffer的代码示例:
//在设备驱动程序中申请bounce buffer
dma_addr_t dma_handle;
struct scatterlist sg;
int rc;
size_t length = sizeof(struct my_data);
void *buffer = kmalloc(length, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
rc = dma_map_sg(dev, &sg, 1, DMA_FROM_DEVICE); //映射scatterlist到物理页框
if (rc != 1)
goto err_free;
dma_handle = sg_dma_address(&sg);
//在bounce buffer和真正的物理地址之间进行一次数据拷贝
void *bounce_buffer = dma_alloc_coherent(dev, length, &dma_handle, GFP_KERNEL)
memcpy(bounce_buffer, buffer, length);
dma_sync_sg_for_device(dev, &sg, 1, DMA_TO_DEVICE); //同步scatterlist
/* ... */
//释放bounce buffer
dma_sync_sg_for_cpu(dev, &sg, 1, DMA_FROM_DEVICE); //同步scatterlist
dma_free_coherent(dev, length, bounce_buffer, dma_handle);
以下是停用cache的示例代码:
//停用cache
dma_cache_wback_inv(sg->page, sg->offset, sg->length);