- 论坛徽章:
- 0
|
ixp425的pci_map函数
dma_addr_t ixp425_pci_map_single(void *virt, size_t size, int direction)
{
dma_addr_t dma_addr;
unsigned long flags;
void *safe;
DBG("ixp425_map_single(virt=%p,size=%d,dir=%x)\n",
virt, size, direction);
dma_addr = virt_to_bus(virt);
if(((u32)virt + size) >= (CONFIG_KERNEL_START + SZ_64M)) {
safe = alloc_safe_buffer(virt, size, &dma_addr);
if (!safe) {
printk("%s: Could not allocate safe buffer",
__FILE__);
return 0;
}
DBG("unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", virt,
(void *)virt_to_phys(virt), safe, (void *)dma_addr);
/*
* Only need to copy if DMAing to device
*/
if((direction == PCI_DMA_TODEVICE) ||
(direction == PCI_DMA_BIDIRECTIONAL)) {
memcpy(safe, virt, size);
}
consistent_sync(safe, size, direction);
}
else
consistent_sync(virt, size, direction);
return dma_addr;
}
void ixp425_pci_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
{
void *safe, *unsafe;
unsigned long flags;
struct safe_buffer *safe_buf;
DBG("ixp425_unmap_single(ptr=%p, size=%d, dir=%x)\n",
(void *)dma_addr, size, direction);
if ((safe_buf = find_safe_buffer(dma_addr, &unsafe))) {
if((direction == PCI_DMA_FROMDEVICE) ||
(direction == PCI_DMA_BIDIRECTIONAL)) {
DBG("copyback unsafe %p, safe %p, size %d\n", unsafe, safe_buf->safe, size);
consistent_sync(safe_buf->safe, size, direction);
memcpy(unsafe, safe_buf->safe, size);
}
free_safe_buffer(safe_buf);
} else {
/*
* Assume this is normal memory. We have a possible
* OOPs here if someone sends us a bad dma_addr_t.
*/
unsafe = bus_to_virt(dma_addr);
consistent_sync(unsafe, size, direction);
}
}
这个地方也想请教一下,一直对DMA硬件如何实现的不清楚:
1)i386平台的DMA的寄存器是如何设置的?
2)网卡中的数据是如何通过DMA传到内存中的?
[ 本帖最后由 bekars 于 2007-4-25 16:10 编辑 ] |
|