Commit 9552f3ff authored by Ben Collins's avatar Ben Collins

IEEE1394(r1154): Cleanup dma routines, and use vmalloc for sglist allocation.

parent c59badd4
...@@ -26,11 +26,11 @@ void dma_prog_region_init(struct dma_prog_region *prog) ...@@ -26,11 +26,11 @@ void dma_prog_region_init(struct dma_prog_region *prog)
int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev) int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev)
{ {
/* round up to page size */ /* round up to page size */
n_bytes = round_up_to_page(n_bytes); n_bytes = PAGE_ALIGN(n_bytes);
prog->n_pages = n_bytes / PAGE_SIZE; prog->n_pages = n_bytes >> PAGE_SHIFT;
prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr); prog->kvirt = pci_alloc_consistent(dev, n_bytes, &prog->bus_addr);
if (!prog->kvirt) { if (!prog->kvirt) {
printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
dma_prog_region_free(prog); dma_prog_region_free(prog);
...@@ -45,7 +45,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, ...@@ -45,7 +45,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
void dma_prog_region_free(struct dma_prog_region *prog) void dma_prog_region_free(struct dma_prog_region *prog)
{ {
if (prog->kvirt) { if (prog->kvirt) {
pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr); pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT, prog->kvirt, prog->bus_addr);
} }
prog->kvirt = NULL; prog->kvirt = NULL;
...@@ -67,44 +67,42 @@ void dma_region_init(struct dma_region *dma) ...@@ -67,44 +67,42 @@ void dma_region_init(struct dma_region *dma)
int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction) int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction)
{ {
unsigned int i, n_pages; unsigned int i;
/* round up to page size */ /* round up to page size */
n_bytes = round_up_to_page(n_bytes); n_bytes = PAGE_ALIGN(n_bytes);
n_pages = n_bytes / PAGE_SIZE; dma->n_pages = n_bytes >> PAGE_SHIFT;
dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE); dma->kvirt = vmalloc_32(n_bytes);
if (!dma->kvirt) { if (!dma->kvirt) {
printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n");
goto err; goto err;
} }
dma->n_pages = n_pages;
/* Clear the ram out, no junk to the user */ /* Clear the ram out, no junk to the user */
memset(dma->kvirt, 0, n_pages * PAGE_SIZE); memset(dma->kvirt, 0, n_bytes);
/* allocate scatter/gather list */ /* allocate scatter/gather list */
dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL); dma->sglist = vmalloc(dma->n_pages * sizeof(*dma->sglist));
if (!dma->sglist) { if (!dma->sglist) {
printk(KERN_ERR "dma_region_alloc: kmalloc(sglist) failed\n"); printk(KERN_ERR "dma_region_alloc: vmalloc(sglist) failed\n");
goto err; goto err;
} }
/* just to be safe - this will become unnecessary once sglist->address goes away */ /* just to be safe - this will become unnecessary once sglist->address goes away */
memset(dma->sglist, 0, dma->n_pages * sizeof(struct scatterlist)); memset(dma->sglist, 0, dma->n_pages * sizeof(*dma->sglist));
/* fill scatter/gather list with pages */ /* fill scatter/gather list with pages */
for (i = 0; i < dma->n_pages; i++) { for (i = 0; i < dma->n_pages; i++) {
unsigned long va = (unsigned long) dma->kvirt + i * PAGE_SIZE; unsigned long va = (unsigned long) dma->kvirt + (i << PAGE_SHIFT);
dma->sglist[i].page = vmalloc_to_page((void *)va); dma->sglist[i].page = vmalloc_to_page((void *)va);
dma->sglist[i].length = PAGE_SIZE; dma->sglist[i].length = PAGE_SIZE;
} }
/* map sglist to the IOMMU */ /* map sglist to the IOMMU */
dma->n_dma_pages = pci_map_sg(dev, &dma->sglist[0], dma->n_pages, direction); dma->n_dma_pages = pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
if (dma->n_dma_pages == 0) { if (dma->n_dma_pages == 0) {
printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n");
...@@ -130,7 +128,7 @@ void dma_region_free(struct dma_region *dma) ...@@ -130,7 +128,7 @@ void dma_region_free(struct dma_region *dma)
} }
if (dma->sglist) { if (dma->sglist) {
kfree(dma->sglist); vfree(dma->sglist);
dma->sglist = NULL; dma->sglist = NULL;
} }
...@@ -199,7 +197,7 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *ty ...@@ -199,7 +197,7 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *ty
goto out; goto out;
if ( (address < (unsigned long) area->vm_start) || if ( (address < (unsigned long) area->vm_start) ||
(address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) ) (address > (unsigned long) area->vm_start + (dma->n_pages << PAGE_SHIFT)) )
goto out; goto out;
if (type) if (type)
...@@ -229,7 +227,7 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_st ...@@ -229,7 +227,7 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_st
/* check the length */ /* check the length */
size = vma->vm_end - vma->vm_start; size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE * dma->n_pages)) if (size > (dma->n_pages << PAGE_SHIFT))
return -EINVAL; return -EINVAL;
vma->vm_ops = &dma_region_vm_ops; vma->vm_ops = &dma_region_vm_ops;
......
...@@ -73,12 +73,4 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s ...@@ -73,12 +73,4 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s
relative to the beginning of the dma_region */ relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset); dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset);
/* round up a number of bytes to be a multiple of the PAGE_SIZE */
static inline unsigned long round_up_to_page(unsigned long len)
{
if (len % PAGE_SIZE)
len += PAGE_SIZE - (len % PAGE_SIZE);
return len;
}
#endif /* IEEE1394_DMA_H */ #endif /* IEEE1394_DMA_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment