summaryrefslogtreecommitdiffstats
path: root/include/linux/dma-buf.h
diff options
context:
space:
mode:
authorSumit Semwal <sumit.semwal@ti.com>2011-12-26 04:23:15 -0500
committerDave Airlie <airlied@redhat.com>2012-01-06 05:20:21 -0500
commitd15bd7ee445d0702ad801fdaece348fdb79e6581 (patch)
tree6f18212787e77b9615c955506adda516206ecbac /include/linux/dma-buf.h
parent805a6af8dba5dfdd35ec35dc52ec0122400b2610 (diff)
dma-buf: Introduce dma buffer sharing mechanism
This is the first step in defining a dma buffer sharing mechanism. A new buffer object dma_buf is added, with operations and API to allow easy sharing of this buffer object across devices. The framework allows: - creation of a buffer object, its association with a file pointer, and associated allocator-defined operations on that buffer. This operation is called the 'export' operation. - different devices to 'attach' themselves to this exported buffer object, to facilitate backing storage negotiation, using dma_buf_attach() API. - the exported buffer object to be shared with the other entity by asking for its 'file-descriptor (fd)', and sharing the fd across. - a received fd to get the buffer object back, where it can be accessed using the associated exporter-defined operations. - the exporter and user to share the scatterlist associated with this buffer object using map_dma_buf and unmap_dma_buf operations. Atleast one 'attach()' call is required to be made prior to calling the map_dma_buf() operation. Couple of building blocks in map_dma_buf() are added to ease introduction of sync'ing across exporter and users, and late allocation by the exporter. For this first version, this framework will work with certain conditions: - *ONLY* exporter will be allowed to mmap to userspace (outside of this framework - mmap is not a buffer object operation), - currently, *ONLY* users that do not need CPU access to the buffer are allowed. More details are there in the documentation patch. This is based on design suggestions from many people at the mini-summits[1], most notably from Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and Daniel Vetter <daniel@ffwll.ch>. The implementation is inspired from proof-of-concept patch-set from Tomasz Stanislawski <t.stanislaws@samsung.com>, who demonstrated buffer sharing between two v4l2 devices. [2] [1]: https://wiki.linaro.org/OfficeofCTO/MemoryManagement [2]: http://lwn.net/Articles/454389 Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Sumit Semwal <sumit.semwal@ti.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-and-Tested-by: Rob Clark <rob.clark@linaro.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include/linux/dma-buf.h')
-rw-r--r--include/linux/dma-buf.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
new file mode 100644
index 000000000000..f8ac076afa52
--- /dev/null
+++ b/include/linux/dma-buf.h
@@ -0,0 +1,176 @@
1/*
2 * Header file for dma buffer sharing framework.
3 *
4 * Copyright(C) 2011 Linaro Limited. All rights reserved.
5 * Author: Sumit Semwal <sumit.semwal@ti.com>
6 *
7 * Many thanks to linaro-mm-sig list, and specially
8 * Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and
9 * Daniel Vetter <daniel@ffwll.ch> for their support in creation and
10 * refining of this idea.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published by
14 * the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24#ifndef __DMA_BUF_H__
25#define __DMA_BUF_H__
26
27#include <linux/file.h>
28#include <linux/err.h>
29#include <linux/device.h>
30#include <linux/scatterlist.h>
31#include <linux/list.h>
32#include <linux/dma-mapping.h>
33
34struct dma_buf;
35struct dma_buf_attachment;
36
37/**
38 * struct dma_buf_ops - operations possible on struct dma_buf
39 * @attach: [optional] allows different devices to 'attach' themselves to the
40 * given buffer. It might return -EBUSY to signal that backing storage
41 * is already allocated and incompatible with the requirements
42 * of requesting device.
43 * @detach: [optional] detach a given device from this buffer.
44 * @map_dma_buf: returns list of scatter pages allocated, increases usecount
45 * of the buffer. Requires atleast one attach to be called
46 * before. Returned sg list should already be mapped into
47 * _device_ address space. This call may sleep. May also return
48 * -EINTR. Should return -EINVAL if attach hasn't been called yet.
49 * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter
50 * pages.
51 * @release: release this buffer; to be called after the last dma_buf_put.
52 */
53struct dma_buf_ops {
54 int (*attach)(struct dma_buf *, struct device *,
55 struct dma_buf_attachment *);
56
57 void (*detach)(struct dma_buf *, struct dma_buf_attachment *);
58
59 /* For {map,unmap}_dma_buf below, any specific buffer attributes
60 * required should get added to device_dma_parameters accessible
61 * via dev->dma_params.
62 */
63 struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *,
64 enum dma_data_direction);
65 void (*unmap_dma_buf)(struct dma_buf_attachment *,
66 struct sg_table *);
67 /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
68 * if the call would block.
69 */
70
71 /* after final dma_buf_put() */
72 void (*release)(struct dma_buf *);
73
74};
75
76/**
77 * struct dma_buf - shared buffer object
78 * @size: size of the buffer
79 * @file: file pointer used for sharing buffers across, and for refcounting.
80 * @attachments: list of dma_buf_attachment that denotes all devices attached.
81 * @ops: dma_buf_ops associated with this buffer object.
82 * @priv: exporter specific private data for this buffer object.
83 */
84struct dma_buf {
85 size_t size;
86 struct file *file;
87 struct list_head attachments;
88 const struct dma_buf_ops *ops;
89 /* mutex to serialize list manipulation and other ops */
90 struct mutex lock;
91 void *priv;
92};
93
94/**
95 * struct dma_buf_attachment - holds device-buffer attachment data
96 * @dmabuf: buffer for this attachment.
97 * @dev: device attached to the buffer.
98 * @node: list of dma_buf_attachment.
99 * @priv: exporter specific attachment data.
100 *
101 * This structure holds the attachment information between the dma_buf buffer
102 * and its user device(s). The list contains one attachment struct per device
103 * attached to the buffer.
104 */
105struct dma_buf_attachment {
106 struct dma_buf *dmabuf;
107 struct device *dev;
108 struct list_head node;
109 void *priv;
110};
111
112#ifdef CONFIG_DMA_SHARED_BUFFER
113struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
114 struct device *dev);
115void dma_buf_detach(struct dma_buf *dmabuf,
116 struct dma_buf_attachment *dmabuf_attach);
117struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops,
118 size_t size, int flags);
119int dma_buf_fd(struct dma_buf *dmabuf);
120struct dma_buf *dma_buf_get(int fd);
121void dma_buf_put(struct dma_buf *dmabuf);
122
123struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
124 enum dma_data_direction);
125void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *);
126#else
127
128static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
129 struct device *dev)
130{
131 return ERR_PTR(-ENODEV);
132}
133
134static inline void dma_buf_detach(struct dma_buf *dmabuf,
135 struct dma_buf_attachment *dmabuf_attach)
136{
137 return;
138}
139
140static inline struct dma_buf *dma_buf_export(void *priv,
141 struct dma_buf_ops *ops,
142 size_t size, int flags)
143{
144 return ERR_PTR(-ENODEV);
145}
146
147static inline int dma_buf_fd(struct dma_buf *dmabuf)
148{
149 return -ENODEV;
150}
151
152static inline struct dma_buf *dma_buf_get(int fd)
153{
154 return ERR_PTR(-ENODEV);
155}
156
157static inline void dma_buf_put(struct dma_buf *dmabuf)
158{
159 return;
160}
161
162static inline struct sg_table *dma_buf_map_attachment(
163 struct dma_buf_attachment *attach, enum dma_data_direction write)
164{
165 return ERR_PTR(-ENODEV);
166}
167
168static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
169 struct sg_table *sg)
170{
171 return;
172}
173
174#endif /* CONFIG_DMA_SHARED_BUFFER */
175
176#endif /* __DMA_BUF_H__ */