- 论坛徽章:
- 0
|
事实上我昨天就仔细的看了下DMA-mapping.txt这篇文档 今天又重看了下 这篇文章确实写的很好 补充了很多ldd3没点到的地方 不过这一切对解答我的疑惑没有什么帮助
我知道是我理解不够 所以出现了一些看上去自相矛盾的地方
这是pci_alloc_consistent在pci_iommu.c中的源码:
/* Allocate and map kernel buffer using consistent mode DMA for PCI
device. Returns non-NULL cpu-view pointer to the buffer if
successful and sets *DMA_ADDRP to the pci side dma address as well,
else DMA_ADDRP is undefined. */
void *
pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
{
void *cpu_addr;
long order = get_order(size);
gfp_t gfp = GFP_ATOMIC;
try_again:
cpu_addr = (void *)__get_free_pages(gfp, order);
if (! cpu_addr) {
printk(KERN_INFO "pci_alloc_consistent: "
"get_free_pages failed from %p\n",
__builtin_return_address(0));
/* ??? Really atomic allocation? Otherwise we could play
with vmalloc and sg if we can't find contiguous memory. */
return NULL;
}
memset(cpu_addr, 0, size);
*dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
if (*dma_addrp == 0) {
free_pages((unsigned long)cpu_addr, order);
if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
return NULL;
/* The address doesn't fit required mask and we
do not have iommu. Try again with GFP_DMA. */
gfp |= GFP_DMA;
goto try_again;
}
DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
size, cpu_addr, *dma_addrp, __builtin_return_address(0));
return cpu_addr;
}
代码很简单 第一部分就是分配内存 直到分配成功为止 而第二部分就是调用pci_map_single_1建立dma映射 同样在这个文件里 有有关pci_map_single_1的说明:
/* Map a single buffer of the indicated size for PCI DMA in streaming
mode. The 32-bit PCI bus mastering address to use is returned.
Once the device is given the dma address, the device owns this memory
until either pci_unmap_single or pci_dma_sync_single is performed. */
static dma_addr_t
pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
int dac_allowed)
不明白既然是一致性 为啥里面建立映射调用的是建立流模式的函数 这是让我搞不懂的地方
也许奥秘就在pci_map_single_1 具体实现里 不过我不大看的懂。。。
[ 本帖最后由 duanius 于 2008-3-19 12:24 编辑 ] |
|