at v3.4 8.3 kB view raw
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/scatterlist.h> 30#include <linux/list.h> 31#include <linux/dma-mapping.h> 32#include <linux/fs.h> 33 34struct device; 35struct dma_buf; 36struct dma_buf_attachment; 37 38/** 39 * struct dma_buf_ops - operations possible on struct dma_buf 40 * @attach: [optional] allows different devices to 'attach' themselves to the 41 * given buffer. It might return -EBUSY to signal that backing storage 42 * is already allocated and incompatible with the requirements 43 * of requesting device. 44 * @detach: [optional] detach a given device from this buffer. 45 * @map_dma_buf: returns list of scatter pages allocated, increases usecount 46 * of the buffer. Requires atleast one attach to be called 47 * before. Returned sg list should already be mapped into 48 * _device_ address space. This call may sleep. May also return 49 * -EINTR. Should return -EINVAL if attach hasn't been called yet. 50 * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter 51 * pages. 52 * @release: release this buffer; to be called after the last dma_buf_put. 53 * @begin_cpu_access: [optional] called before cpu access to invalidate cpu 54 * caches and allocate backing storage (if not yet done) 55 * respectively pin the objet into memory. 56 * @end_cpu_access: [optional] called after cpu access to flush cashes. 57 * @kmap_atomic: maps a page from the buffer into kernel address 58 * space, users may not block until the subsequent unmap call. 59 * This callback must not sleep. 60 * @kunmap_atomic: [optional] unmaps a atomically mapped page from the buffer. 61 * This Callback must not sleep. 62 * @kmap: maps a page from the buffer into kernel address space. 63 * @kunmap: [optional] unmaps a page from the buffer. 64 */ 65struct dma_buf_ops { 66 int (*attach)(struct dma_buf *, struct device *, 67 struct dma_buf_attachment *); 68 69 void (*detach)(struct dma_buf *, struct dma_buf_attachment *); 70 71 /* For {map,unmap}_dma_buf below, any specific buffer attributes 72 * required should get added to device_dma_parameters accessible 73 * via dev->dma_params. 74 */ 75 struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, 76 enum dma_data_direction); 77 void (*unmap_dma_buf)(struct dma_buf_attachment *, 78 struct sg_table *, 79 enum dma_data_direction); 80 /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY 81 * if the call would block. 82 */ 83 84 /* after final dma_buf_put() */ 85 void (*release)(struct dma_buf *); 86 87 int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, 88 enum dma_data_direction); 89 void (*end_cpu_access)(struct dma_buf *, size_t, size_t, 90 enum dma_data_direction); 91 void *(*kmap_atomic)(struct dma_buf *, unsigned long); 92 void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); 93 void *(*kmap)(struct dma_buf *, unsigned long); 94 void (*kunmap)(struct dma_buf *, unsigned long, void *); 95}; 96 97/** 98 * struct dma_buf - shared buffer object 99 * @size: size of the buffer 100 * @file: file pointer used for sharing buffers across, and for refcounting. 101 * @attachments: list of dma_buf_attachment that denotes all devices attached. 102 * @ops: dma_buf_ops associated with this buffer object. 103 * @priv: exporter specific private data for this buffer object. 104 */ 105struct dma_buf { 106 size_t size; 107 struct file *file; 108 struct list_head attachments; 109 const struct dma_buf_ops *ops; 110 /* mutex to serialize list manipulation and attach/detach */ 111 struct mutex lock; 112 void *priv; 113}; 114 115/** 116 * struct dma_buf_attachment - holds device-buffer attachment data 117 * @dmabuf: buffer for this attachment. 118 * @dev: device attached to the buffer. 119 * @node: list of dma_buf_attachment. 120 * @priv: exporter specific attachment data. 121 * 122 * This structure holds the attachment information between the dma_buf buffer 123 * and its user device(s). The list contains one attachment struct per device 124 * attached to the buffer. 125 */ 126struct dma_buf_attachment { 127 struct dma_buf *dmabuf; 128 struct device *dev; 129 struct list_head node; 130 void *priv; 131}; 132 133/** 134 * get_dma_buf - convenience wrapper for get_file. 135 * @dmabuf: [in] pointer to dma_buf 136 * 137 * Increments the reference count on the dma-buf, needed in case of drivers 138 * that either need to create additional references to the dmabuf on the 139 * kernel side. For example, an exporter that needs to keep a dmabuf ptr 140 * so that subsequent exports don't create a new dmabuf. 141 */ 142static inline void get_dma_buf(struct dma_buf *dmabuf) 143{ 144 get_file(dmabuf->file); 145} 146 147#ifdef CONFIG_DMA_SHARED_BUFFER 148struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 149 struct device *dev); 150void dma_buf_detach(struct dma_buf *dmabuf, 151 struct dma_buf_attachment *dmabuf_attach); 152struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, 153 size_t size, int flags); 154int dma_buf_fd(struct dma_buf *dmabuf, int flags); 155struct dma_buf *dma_buf_get(int fd); 156void dma_buf_put(struct dma_buf *dmabuf); 157 158struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, 159 enum dma_data_direction); 160void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, 161 enum dma_data_direction); 162int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, 163 enum dma_data_direction dir); 164void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, 165 enum dma_data_direction dir); 166void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); 167void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); 168void *dma_buf_kmap(struct dma_buf *, unsigned long); 169void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); 170#else 171 172static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 173 struct device *dev) 174{ 175 return ERR_PTR(-ENODEV); 176} 177 178static inline void dma_buf_detach(struct dma_buf *dmabuf, 179 struct dma_buf_attachment *dmabuf_attach) 180{ 181 return; 182} 183 184static inline struct dma_buf *dma_buf_export(void *priv, 185 const struct dma_buf_ops *ops, 186 size_t size, int flags) 187{ 188 return ERR_PTR(-ENODEV); 189} 190 191static inline int dma_buf_fd(struct dma_buf *dmabuf, int flags) 192{ 193 return -ENODEV; 194} 195 196static inline struct dma_buf *dma_buf_get(int fd) 197{ 198 return ERR_PTR(-ENODEV); 199} 200 201static inline void dma_buf_put(struct dma_buf *dmabuf) 202{ 203 return; 204} 205 206static inline struct sg_table *dma_buf_map_attachment( 207 struct dma_buf_attachment *attach, enum dma_data_direction write) 208{ 209 return ERR_PTR(-ENODEV); 210} 211 212static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, 213 struct sg_table *sg, enum dma_data_direction dir) 214{ 215 return; 216} 217 218static inline int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, 219 size_t start, size_t len, 220 enum dma_data_direction dir) 221{ 222 return -ENODEV; 223} 224 225static inline void dma_buf_end_cpu_access(struct dma_buf *dmabuf, 226 size_t start, size_t len, 227 enum dma_data_direction dir) 228{ 229} 230 231static inline void *dma_buf_kmap_atomic(struct dma_buf *dmabuf, 232 unsigned long pnum) 233{ 234 return NULL; 235} 236 237static inline void dma_buf_kunmap_atomic(struct dma_buf *dmabuf, 238 unsigned long pnum, void *vaddr) 239{ 240} 241 242static inline void *dma_buf_kmap(struct dma_buf *dmabuf, unsigned long pnum) 243{ 244 return NULL; 245} 246 247static inline void dma_buf_kunmap(struct dma_buf *dmabuf, 248 unsigned long pnum, void *vaddr) 249{ 250} 251#endif /* CONFIG_DMA_SHARED_BUFFER */ 252 253#endif /* __DMA_BUF_H__ */