Messages in this thread | | | Date | Sun, 21 Mar 2004 16:23:49 -0800 | From | William Lee Irwin III <> | Subject | Re: can device drivers return non-ram via vm_ops->nopage? |
| |
On Sun, Mar 21, 2004 at 11:45:15PM +0000, Russell King wrote: > Ok, splitting hairs, for the coherent contiguous case, what about: > int dma_coherent_map(struct vm_area_struct *vma, void *cpu_addr, > dma_addr_t dma_addr, size_t size); > and x86 would be: > #define dma_coherent_map(vma,cpu_addr,dma_addr,size) \ > remap_page_range(vma, vma->vm_start, __pa(cpu_addr), \ > size, vma->vm_page_prot) > This then leaves the PCI BAR case and the DMA coherent SG buffer case, > though neither of those fall within my personal problem space at present.
Can we get an offset into the area as one of the args? Then scatter/gather should be trivially constructible (via iteration) from the interface. Maybe something like:
struct dma_scatterlist { dma_addr_t dma_addr; /* DMA address */ void *cpu_addr; /* cpu address */ unsigned long length; /* in units of pages */ };
int dma_mmap_coherent_sg(struct dma_scatterlist *sglist, int nr_sglist_elements, /* length of sglist */ struct vm_area_struct *vma, /* for address space */ unsigned long address, /* user virtual address */ unsigned long offset, /* offset (in pages) */ unsigned long nr_pages); /* length (in pages) */
int dma_munmap_coherent_sg(struct dma_scatterlist *sglist, int nr_sglist_elements, /* length of sglist */ struct vm_area_struct *vma, /* for address space */ unsigned long address, /* user virtual address */ unsigned long offset, /* offset (in pages) */ unsigned long nr_pages); /* length (in pages) */
int dma_alloc_coherent_sg(struct dma_scatterlist **sglist, unsigned long length); /* length in pages */
int dma_free_coherent_sg(struct dma_scatterlist **sglist, unsigned long length); /* length in pages */
Would be useful? And these in turn would drive the dma_alloc_coherent() and helpers like:
int dma_mmap_coherent(struct vm_area_struct *vma, unsigned long address, dma_addr_t dma_addr, /* DMA address */ void *cpu_addr, /* cpu address */ unsigned long nr_pages); /* length (in pages) */
int dma_munmap_coherent(struct vm_area_struct *vma, unsigned long address, dma_addr_t dma_addr, /* DMA address */ void *cpu_addr, /* cpu address */ unsigned long nr_pages); /* length (in pages) */
Does any of this sound like it's on the right track API-wise?
My thought on attacking the scatter/gather issue is basically centered around "they're going to try to do it anyway, and if they don't have something there to do it for them, they'll get it wrong."
-- wli - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |