Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cris-mirror.git] / drivers / gpu / drm / i915 / selftests / mock_dmabuf.c
blob302f7d1036359ab47db4009037561b99e2d617d6
1 /*
2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
25 #include "mock_dmabuf.h"
27 static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
28 enum dma_data_direction dir)
30 struct mock_dmabuf *mock = to_mock(attachment->dmabuf);
31 struct sg_table *st;
32 struct scatterlist *sg;
33 int i, err;
35 st = kmalloc(sizeof(*st), GFP_KERNEL);
36 if (!st)
37 return ERR_PTR(-ENOMEM);
39 err = sg_alloc_table(st, mock->npages, GFP_KERNEL);
40 if (err)
41 goto err_free;
43 sg = st->sgl;
44 for (i = 0; i < mock->npages; i++) {
45 sg_set_page(sg, mock->pages[i], PAGE_SIZE, 0);
46 sg = sg_next(sg);
49 if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
50 err = -ENOMEM;
51 goto err_st;
54 return st;
56 err_st:
57 sg_free_table(st);
58 err_free:
59 kfree(st);
60 return ERR_PTR(err);
63 static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
64 struct sg_table *st,
65 enum dma_data_direction dir)
67 dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
68 sg_free_table(st);
69 kfree(st);
72 static void mock_dmabuf_release(struct dma_buf *dma_buf)
74 struct mock_dmabuf *mock = to_mock(dma_buf);
75 int i;
77 for (i = 0; i < mock->npages; i++)
78 put_page(mock->pages[i]);
80 kfree(mock);
83 static void *mock_dmabuf_vmap(struct dma_buf *dma_buf)
85 struct mock_dmabuf *mock = to_mock(dma_buf);
87 return vm_map_ram(mock->pages, mock->npages, 0, PAGE_KERNEL);
90 static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
92 struct mock_dmabuf *mock = to_mock(dma_buf);
94 vm_unmap_ram(vaddr, mock->npages);
97 static void *mock_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
99 struct mock_dmabuf *mock = to_mock(dma_buf);
101 return kmap_atomic(mock->pages[page_num]);
104 static void mock_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
106 kunmap_atomic(addr);
109 static void *mock_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
111 struct mock_dmabuf *mock = to_mock(dma_buf);
113 return kmap(mock->pages[page_num]);
116 static void mock_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
118 struct mock_dmabuf *mock = to_mock(dma_buf);
120 return kunmap(mock->pages[page_num]);
123 static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
125 return -ENODEV;
128 static const struct dma_buf_ops mock_dmabuf_ops = {
129 .map_dma_buf = mock_map_dma_buf,
130 .unmap_dma_buf = mock_unmap_dma_buf,
131 .release = mock_dmabuf_release,
132 .map = mock_dmabuf_kmap,
133 .map_atomic = mock_dmabuf_kmap_atomic,
134 .unmap = mock_dmabuf_kunmap,
135 .unmap_atomic = mock_dmabuf_kunmap_atomic,
136 .mmap = mock_dmabuf_mmap,
137 .vmap = mock_dmabuf_vmap,
138 .vunmap = mock_dmabuf_vunmap,
141 static struct dma_buf *mock_dmabuf(int npages)
143 struct mock_dmabuf *mock;
144 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
145 struct dma_buf *dmabuf;
146 int i;
148 mock = kmalloc(sizeof(*mock) + npages * sizeof(struct page *),
149 GFP_KERNEL);
150 if (!mock)
151 return ERR_PTR(-ENOMEM);
153 mock->npages = npages;
154 for (i = 0; i < npages; i++) {
155 mock->pages[i] = alloc_page(GFP_KERNEL);
156 if (!mock->pages[i])
157 goto err;
160 exp_info.ops = &mock_dmabuf_ops;
161 exp_info.size = npages * PAGE_SIZE;
162 exp_info.flags = O_CLOEXEC;
163 exp_info.priv = mock;
165 dmabuf = dma_buf_export(&exp_info);
166 if (IS_ERR(dmabuf))
167 goto err;
169 return dmabuf;
171 err:
172 while (i--)
173 put_page(mock->pages[i]);
174 kfree(mock);
175 return ERR_PTR(-ENOMEM);