当前位置:网站首页>ion_ mmap

ion_ mmap

2022-06-11 01:05:00 wmzjzwlzs

static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
    struct ion_buffer *buffer = dmabuf->priv;
    int ret = 0;

    if (!buffer->heap->ops->map_user) {
        pr_err("%s: this heap does not define a method for mapping to userspace\n",
               __func__);
        return -EINVAL;
    }

    if (!(buffer->flags & ION_FLAG_CACHED))
        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);

    mutex_lock(&buffer->lock);
    /* now map it to userspace */
    ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma);
    mutex_unlock(&buffer->lock);

    if (ret)
        pr_err("%s: failure mapping buffer to userspace\n",
               __func__);

    return ret;
}

int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
              struct vm_area_struct *vma)
{
    struct sg_table *table = buffer->sg_table;
    unsigned long addr = vma->vm_start;
    unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
    struct scatterlist *sg;
    int i;
    int ret;

    for_each_sg(table->sgl, sg, table->nents, i) {
        struct page *page = sg_page(sg);
        unsigned long remainder = vma->vm_end - addr;
        unsigned long len = sg->length;

        if (offset >= sg->length) {
            offset -= sg->length;
            continue;
        } else if (offset) {
            page += offset / PAGE_SIZE;
            len = sg->length - offset;
            offset = 0;
        }
        len = min(len, remainder);
        ret = remap_pfn_range(vma, addr, page_to_pfn(page), len,
                      vma->vm_page_prot);
        if (ret)
            return ret;
        addr += len;
        if (addr >= vma->vm_end)
            return 0;
    }

    return 0;
}

原网站

版权声明
本文为[wmzjzwlzs]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206102357260121.html