static int __videobuf_mmap_mapper(struct videobuf_queue *q,
				  struct videobuf_buffer *buf,
				  struct vm_area_struct *vma)
{
	struct videobuf_vmalloc_memory *mem;
	struct videobuf_mapping *map;
	int retval, pages;

	dprintk(1, "%s\n", __func__);

	/* create mapping + update buffer list */
	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (NULL == map)
		return -ENOMEM;

	buf->map = map;
	map->start = vma->vm_start;
	map->end   = vma->vm_end;
	map->q     = q;

	buf->baddr = vma->vm_start;

	mem = buf->priv;
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);

	pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
	mem->vmalloc = vmalloc_user(pages);
	if (!mem->vmalloc) {
		printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
		goto error;
	}
	dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vmalloc, pages);

	/* Try to remap memory */
	retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
	if (retval < 0) {
		printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
		vfree(mem->vmalloc);
		goto error;
	}

	vma->vm_ops          = &videobuf_vm_ops;
	vma->vm_flags       |= VM_DONTEXPAND | VM_RESERVED;
	vma->vm_private_data = map;

	dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
		map, q, vma->vm_start, vma->vm_end,
		(long int)buf->bsize,
		vma->vm_pgoff, buf->i);

	videobuf_vm_open(vma);

	return 0;

error:
	mem = NULL;
	kfree(map);
	return -ENOMEM;
}
Exemple #2
0
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
			struct videobuf_buffer *buf, struct vm_area_struct *vma)
{
	struct videobuf_marucam_memory *mem;
	struct videobuf_mapping *map;
	int retval, pages;

	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (NULL == map) {
		marucam_err("Failed to allocate the video buffer map\n");
		return -ENOMEM;
	}

	buf->map = map;
	map->q = q;

	buf->baddr = vma->vm_start;

	mem = buf->priv;
	BUG_ON(!mem);
	mem->mapped = 1;
	MAGIC_CHECK(mem->magic, MAGIC_MARUCAM_MEM);

	pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	retval = remap_pfn_range(vma, vma->vm_start,
			(((struct marucam_device *)q->priv_data)->mem_base
			+ vma->vm_pgoff) >> PAGE_SHIFT,
			pages, vma->vm_page_prot);
	if (retval < 0) {
		marucam_err("Failed to remap the memory: %d\n", retval);
		mem->mapped = 0;
		mem = NULL;
		kfree(map);
		return -ENOMEM;
	}

	vma->vm_ops		= &videobuf_vm_ops;
	vma->vm_flags		|= VM_DONTEXPAND | VM_RESERVED;
	vma->vm_private_data	= map;

	videobuf_vm_open(vma);

	return 0;
}
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
                                  struct vm_area_struct *vma)
{
    struct videobuf_dma_contig_memory *mem;
    struct videobuf_mapping *map;
    unsigned int first;
    int retval;
    unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;

    dev_dbg(q->dev, "%s\n", __func__);
    if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
        return -EINVAL;

    /* look for first buffer to map */
    for (first = 0; first < VIDEO_MAX_FRAME; first++) {
        if (!q->bufs[first])
            continue;

        if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
            continue;
        if (q->bufs[first]->boff == offset)
            break;
    }
    if (VIDEO_MAX_FRAME == first) {
        dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
                offset);
        return -EINVAL;
    }

    /* create mapping + update buffer list */
    map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
    if (!map)
        return -ENOMEM;

    q->bufs[first]->map = map;
    map->start = vma->vm_start;
    map->end = vma->vm_end;
    map->q = q;

    q->bufs[first]->baddr = vma->vm_start;

    mem = q->bufs[first]->priv;
    BUG_ON(!mem);
    MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);

    mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
    mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
                                    &mem->dma_handle, GFP_KERNEL);
    if (!mem->vaddr) {
        dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
                mem->size);
        goto error;
    }
    dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
            mem->vaddr, mem->size);

    /* Try to remap memory */

    size = vma->vm_end - vma->vm_start;
    size = (size < mem->size) ? size : mem->size;

    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    retval = remap_pfn_range(vma, vma->vm_start,
                             mem->dma_handle >> PAGE_SHIFT,
                             size, vma->vm_page_prot);
    if (retval) {
        dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
        dma_free_coherent(q->dev, mem->size,
                          mem->vaddr, mem->dma_handle);
        goto error;
    }

    vma->vm_ops          = &videobuf_vm_ops;
    vma->vm_flags       |= VM_DONTEXPAND;
    vma->vm_private_data = map;

    dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
            map, q, vma->vm_start, vma->vm_end,
            (long int) q->bufs[first]->bsize,
            vma->vm_pgoff, first);

    videobuf_vm_open(vma);

    return 0;

error:
    kfree(map);
    return -ENOMEM;
}
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
			 struct vm_area_struct *vma)
{
	struct videobuf_vmalloc_memory *mem;
	struct videobuf_mapping *map;
	unsigned int first;
	int retval, pages;
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

	dprintk(1, "%s\n", __func__);
	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
		return -EINVAL;

	/* look for first buffer to map */
	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
		if (NULL == q->bufs[first])
			continue;

		if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
			continue;
		if (q->bufs[first]->boff == offset)
			break;
	}
	if (VIDEO_MAX_FRAME == first) {
		dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
			(vma->vm_pgoff << PAGE_SHIFT));
		return -EINVAL;
	}

	/* create mapping + update buffer list */
	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (NULL == map)
		return -ENOMEM;

	q->bufs[first]->map = map;
	map->start = vma->vm_start;
	map->end   = vma->vm_end;
	map->q     = q;

	q->bufs[first]->baddr = vma->vm_start;

	mem = q->bufs[first]->priv;
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);

	pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
	mem->vmalloc = vmalloc_user(pages);
	if (!mem->vmalloc) {
		printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
		goto error;
	}
	dprintk(1, "vmalloc is at addr %p (%d pages)\n",
		mem->vmalloc, pages);

	/* Try to remap memory */
	retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
	if (retval < 0) {
		printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
		vfree(mem->vmalloc);
		goto error;
	}

	vma->vm_ops          = &videobuf_vm_ops;
	vma->vm_flags       |= VM_DONTEXPAND | VM_RESERVED;
	vma->vm_private_data = map;

	dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
		map, q, vma->vm_start, vma->vm_end,
		(long int) q->bufs[first]->bsize,
		vma->vm_pgoff, first);

	videobuf_vm_open(vma);

	return 0;

error:
	mem = NULL;
	kfree(map);
	return -ENOMEM;
}
Exemple #5
0
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
		struct videobuf_buffer *buf,
		struct vm_area_struct *vma)
{
	struct videobuf_contig_pmem *mem;
	struct videobuf_mapping *map;
	int retval;
	unsigned long size;

	D("%s\n", __func__);

	/* create mapping + update buffer list */
	map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
	if (!map) {
		pr_err("%s: kzalloc failed.\n", __func__);
		return -ENOMEM;
	}

	buf->map = map;
	map->q = q;

	buf->baddr = vma->vm_start;

	mem = buf->priv;
	D("mem = 0x%x\n", (u32)mem);
	D("buf = 0x%x\n", (u32)buf);
	BUG_ON(!mem);
	MAGIC_CHECK(mem->magic, MAGIC_PMEM);

	mem->size = PAGE_ALIGN(buf->bsize);
	mem->y_off = 0;
	mem->cbcr_off = (buf->bsize)*2/3;
	if (buf->i >= 0 && buf->i <= 3)
		mem->buffer_type = OUTPUT_TYPE_P;
	else
		mem->buffer_type = OUTPUT_TYPE_V;

	buf->bsize = mem->size;
	mem->phyaddr = msm_mem_allocate(mem->size);

	if (IS_ERR((void *)mem->phyaddr)) {
		pr_err("%s : pmem memory allocation failed\n", __func__);
		goto error;
	}

	/* Try to remap memory */
	size = vma->vm_end - vma->vm_start;
	size = (size < mem->size) ? size : mem->size;

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	retval = remap_pfn_range(vma, vma->vm_start,
		mem->phyaddr >> PAGE_SHIFT,
		size, vma->vm_page_prot);
	if (retval) {
		pr_err("mmap: remap failed with error %d. ", retval);
		retval = msm_mem_free(mem->phyaddr);
		if (retval < 0)
			printk(KERN_ERR "%s: Invalid memory location\n",
								__func__);
		else {
			mem->phyaddr = 0;
		}
		goto error;
	}

	vma->vm_ops          = &videobuf_vm_ops;
	vma->vm_flags       |= VM_DONTEXPAND;
	vma->vm_private_data = map;

	D("mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
		map, q, vma->vm_start, vma->vm_end,
		(long int)buf->bsize,
		vma->vm_pgoff, buf->i);

	videobuf_vm_open(vma);

	return 0;

error:
	kfree(map);
	return -ENOMEM;
}