1 /* 2 * Header file for dma buffer sharing framework. 3 * 4 * Copyright(C) 2011 Linaro Limited. All rights reserved. 5 * Author: Sumit Semwal <[email protected]> 6 * 7 * Many thanks to linaro-mm-sig list, and specially 8 * Arnd Bergmann <[email protected]>, Rob Clark <[email protected]> and 9 * Daniel Vetter <[email protected]> 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 34 struct dma_buf; 35 struct 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 */ 53 struct 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 */ 84 struct 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 */ 105 struct 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 113 struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 114 struct device *dev); 115 void dma_buf_detach(struct dma_buf *dmabuf, 116 struct dma_buf_attachment *dmabuf_attach); 117 struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops, 118 size_t size, int flags); 119 int dma_buf_fd(struct dma_buf *dmabuf); 120 struct dma_buf *dma_buf_get(int fd); 121 void dma_buf_put(struct dma_buf *dmabuf); 122 123 struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, 124 enum dma_data_direction); 125 void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *); 126 #else 127 128 static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, 129 struct device *dev) 130 { 131 return ERR_PTR(-ENODEV); 132 } 133 134 static inline void dma_buf_detach(struct dma_buf *dmabuf, 135 struct dma_buf_attachment *dmabuf_attach) 136 { 137 return; 138 } 139 140 static 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 147 static inline int dma_buf_fd(struct dma_buf *dmabuf) 148 { 149 return -ENODEV; 150 } 151 152 static inline struct dma_buf *dma_buf_get(int fd) 153 { 154 return ERR_PTR(-ENODEV); 155 } 156 157 static inline void dma_buf_put(struct dma_buf *dmabuf) 158 { 159 return; 160 } 161 162 static 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 168 static 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__ */ 177