linux2.6でDMA転送する方法

久しぶりにPCIバイスでDMA転送するドライバ(linuxカーネルモジュール)を書いたので,メモ.

以下,論理アドレスと,物理アドレスは以下のように表記する.

dma_addr DMAアドレス(物理アドレス,バスアドレスとも)
cpu_addr CPUアドレス(論理アドレス)

DMA関連のAPIlinux/pci.h にて定義されている.

まず,DMA用のバッファを確保するAPI

struct pci_dev *dev;
dma_addr_t dma_addr;
void *cpu_addr;
cpu_addr = pci_alloc_consistent(dev, size, &dma_addr)

解放は

pci_free_consistent(dev, size, cpu_addr, dma_handle);

cpu_addr から struct page を取るAPI

struct page *virt_to_page(void *cpu_addr);