#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
+#include <linux/scatterlist.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
{ printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
-static int debug = 0;
+static int debug;
module_param(debug, int, 0644);
MODULE_DESCRIPTION("helper module to manage video4linux pci dma sg buffers");
sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
+ sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
if (NULL == pg)
goto err;
BUG_ON(PageHighMem(pg));
- sglist[i].page = pg;
- sglist[i].length = PAGE_SIZE;
+ sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
}
return sglist;
sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
+ sg_init_table(sglist, nr_pages);
if (NULL == pages[0])
goto nopage;
if (PageHighMem(pages[0]))
/* DMA to highmem pages might not work */
goto highmem;
- sglist[0].page = pages[0];
- sglist[0].offset = offset;
- sglist[0].length = PAGE_SIZE - offset;
+ sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset);
for (i = 1; i < nr_pages; i++) {
if (NULL == pages[i])
goto nopage;
if (PageHighMem(pages[i]))
goto highmem;
- sglist[i].page = pages[i];
- sglist[i].length = PAGE_SIZE;
+ sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0);
}
return sglist;
map->count--;
if (0 == map->count) {
dprintk(1,"munmap %p q=%p\n",map,q);
- mutex_lock(&q->lock);
+ mutex_lock(&q->vb_lock);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
q->bufs[i]->baddr = 0;
q->ops->buf_release(q,q->bufs[i]);
}
- mutex_unlock(&q->lock);
+ mutex_unlock(&q->vb_lock);
kfree(map);
}
return;
* now ...). Bounce buffers don't work very well for the data rates
* video capture has.
*/
-static struct page*
-videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
- int *type)
+static int
+videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct page *page;
- dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
- vaddr,vma->vm_start,vma->vm_end);
- if (vaddr > vma->vm_end)
- return NOPAGE_SIGBUS;
+ dprintk(3,"fault: fault @ %08lx [vma %08lx-%08lx]\n",
+ (unsigned long)vmf->virtual_address,vma->vm_start,vma->vm_end);
page = alloc_page(GFP_USER | __GFP_DMA32);
if (!page)
- return NOPAGE_OOM;
- clear_user_page(page_address(page), vaddr, page);
- if (type)
- *type = VM_FAULT_MINOR;
- return page;
+ return VM_FAULT_OOM;
+ clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
+ page);
+ vmf->page = page;
+ return 0;
}
static struct vm_operations_struct videobuf_vm_ops =
{
.open = videobuf_vm_open,
.close = videobuf_vm_close,
- .nopage = videobuf_vm_nopage,
+ .fault = videobuf_vm_fault,
};
/* ---------------------------------------------------------------------
.sync = __videobuf_sync,
.mmap_free = __videobuf_mmap_free,
.mmap_mapper = __videobuf_mmap_mapper,
- .copy_to_user = __videobuf_copy_to_user,
+ .video_copy_to_user = __videobuf_copy_to_user,
.copy_stream = __videobuf_copy_stream,
};
unsigned int msize,
void *priv)
{
- videobuf_queue_init(q, ops, dev, irqlock, type, field, msize, priv);
- q->int_ops=&pci_ops;
+ videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
+ priv, &pci_ops);
}
/* --------------------------------------------------------------------- */