From 5375764f9408b8ef1fb8d6cd1ed0efd97dce4824 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 26 Jan 2012 12:27:22 +0100 Subject: dma-buf: Constify ops argument to dma_buf_export() This allows drivers to make the dma buf operations structure constant. Signed-off-by: Laurent Pinchart Reviewed-by: Daniel Vetter Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index f8ac076afa52..86f624141048 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -114,8 +114,8 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *dmabuf_attach); -struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops, - size_t size, int flags); +struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, + size_t size, int flags); int dma_buf_fd(struct dma_buf *dmabuf); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); @@ -138,8 +138,8 @@ static inline void dma_buf_detach(struct dma_buf *dmabuf, } static inline struct dma_buf *dma_buf_export(void *priv, - struct dma_buf_ops *ops, - size_t size, int flags) + const struct dma_buf_ops *ops, + size_t size, int flags) { return ERR_PTR(-ENODEV); } -- cgit From 33ea2dcb39ba50b0b69d1b1dc24702f084b46411 Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Fri, 27 Jan 2012 15:09:27 +0530 Subject: dma-buf: add dma_data_direction to unmap dma_buf_op Some exporters may use DMA map/unmap APIs in dma-buf ops, which require enum dma_data_direction for both map and unmap operations. Thus, the unmap dma_buf_op also needs to have enum dma_data_direction as a parameter. Reported-by: Tomasz Stanislawski Signed-off-by: Sumit Semwal Reviewed-by: Daniel Vetter Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 86f624141048..a885b2689b8f 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -63,7 +63,8 @@ struct dma_buf_ops { struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, - struct sg_table *); + struct sg_table *, + enum dma_data_direction); /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY * if the call would block. */ @@ -122,7 +123,8 @@ void dma_buf_put(struct dma_buf *dmabuf); struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); -void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *); +void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, + enum dma_data_direction); #else static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, @@ -166,7 +168,7 @@ static inline struct sg_table *dma_buf_map_attachment( } static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, - struct sg_table *sg) + struct sg_table *sg, enum dma_data_direction dir) { return; } -- cgit From 55c1c4ca23d0f2736ef7c219d0fb005323ff8ee0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 16 Mar 2012 10:34:02 +0000 Subject: dma-buf: pass flags into dma_buf_fd. We need to pass the flags into dma_buf_fd at this point, so the flags end up doing the right thing for O_CLOEXEC. Signed-off-by: Dave Airlie Signed-off-by: Rob Clark Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index a885b2689b8f..891457a86b30 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -117,7 +117,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *dmabuf_attach); struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, size_t size, int flags); -int dma_buf_fd(struct dma_buf *dmabuf); +int dma_buf_fd(struct dma_buf *dmabuf, int flags); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); -- cgit From f9a24d1ac9cb82baf5ec5efdb6580a9ce0bd5bfc Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 16 Mar 2012 11:04:41 -0500 Subject: dma-buf: add get_dma_buf() Works in a similar way to get_file(), and is needed in cases such as when the exporter needs to also keep a reference to the dmabuf (that is later released with a dma_buf_put()), and possibly other similar cases. Signed-off-by: Rob Clark Reviewed-by: Dave Airlie Reviewed-by: Kyungmin Park Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 891457a86b30..bc4203dc6e18 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -30,6 +30,7 @@ #include #include #include +#include struct dma_buf; struct dma_buf_attachment; @@ -110,6 +111,20 @@ struct dma_buf_attachment { void *priv; }; +/** + * get_dma_buf - convenience wrapper for get_file. + * @dmabuf: [in] pointer to dma_buf + * + * Increments the reference count on the dma-buf, needed in case of drivers + * that either need to create additional references to the dmabuf on the + * kernel side. For example, an exporter that needs to keep a dmabuf ptr + * so that subsequent exports don't create a new dmabuf. + */ +static inline void get_dma_buf(struct dma_buf *dmabuf) +{ + get_file(dmabuf->file); +} + #ifdef CONFIG_DMA_SHARED_BUFFER struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); -- cgit From 6b607e3a658fee490bdabfdeb739a3eb498b1bff Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 19 Mar 2012 00:34:25 +0100 Subject: dma-buf: don't hold the mutex around map/unmap calls The mutex protects the attachment list and hence needs to be held around the callbakc to the exporters (optional) attach/detach functions. Holding the mutex around the map/unmap calls doesn't protect any dma_buf state. Exporters need to properly protect any of their own state anyway (to protect against calls from their own interfaces). So this only makes the locking messier (and lockdep easier to anger). Therefore let's just drop this. v2: Rebased on top of latest dma-buf-next git. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index bc4203dc6e18..24e0f4828711 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -88,7 +88,7 @@ struct dma_buf { struct file *file; struct list_head attachments; const struct dma_buf_ops *ops; - /* mutex to serialize list manipulation and other ops */ + /* mutex to serialize list manipulation and attach/detach */ struct mutex lock; void *priv; }; -- cgit From fc13020e086bfedf2afb95c91c026d5af1f80107 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 20 Mar 2012 00:02:37 +0100 Subject: dma-buf: add support for kernel cpu access Big differences to other contenders in the field (like ion) is that this also supports highmem, so we have to split up the cpu access from the kernel side into a prepare and a kmap step. Prepare is allowed to fail and should do everything required so that the kmap calls can succeed (like swapin/backing storage allocation, flushing, ...). More in-depth explanations will follow in the follow-up documentation patch. Changes in v2: - Clear up begin_cpu_access confusion noticed by Sumit Semwal. - Don't automatically fallback from the _atomic variants to the non-atomic variants. The _atomic callbacks are not allowed to sleep, so we want exporters to make this decision explicit. The function signatures are explicit, so simpler exporters can still use the same function for both. - Make the unmap functions optional. Simpler exporters with permanent mappings don't need to do anything at unmap time. Changes in v3: - Adjust the WARN_ON checks for the new ->ops functions as suggested by Rob Clark and Sumit Semwal. - Rebased on top of latest dma-buf-next git. Changes in v4: - Fixup a missing - in a return -EINVAL; statement. Signed-Off-by: Daniel Vetter Signed-off-by: Rob Clark Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 24e0f4828711..ee7ef9990d9a 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -50,6 +50,17 @@ struct dma_buf_attachment; * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter * pages. * @release: release this buffer; to be called after the last dma_buf_put. + * @begin_cpu_access: [optional] called before cpu access to invalidate cpu + * caches and allocate backing storage (if not yet done) + * respectively pin the objet into memory. + * @end_cpu_access: [optional] called after cpu access to flush cashes. + * @kmap_atomic: maps a page from the buffer into kernel address + * space, users may not block until the subsequent unmap call. + * This callback must not sleep. + * @kunmap_atomic: [optional] unmaps a atomically mapped page from the buffer. + * This Callback must not sleep. + * @kmap: maps a page from the buffer into kernel address space. + * @kunmap: [optional] unmaps a page from the buffer. */ struct dma_buf_ops { int (*attach)(struct dma_buf *, struct device *, @@ -73,6 +84,14 @@ struct dma_buf_ops { /* after final dma_buf_put() */ void (*release)(struct dma_buf *); + int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, + enum dma_data_direction); + void (*end_cpu_access)(struct dma_buf *, size_t, size_t, + enum dma_data_direction); + void *(*kmap_atomic)(struct dma_buf *, unsigned long); + void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); + void *(*kmap)(struct dma_buf *, unsigned long); + void (*kunmap)(struct dma_buf *, unsigned long, void *); }; /** @@ -140,6 +159,14 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); +int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, + enum dma_data_direction dir); +void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, + enum dma_data_direction dir); +void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); +void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); +void *dma_buf_kmap(struct dma_buf *, unsigned long); +void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); #else static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, @@ -188,6 +215,38 @@ static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, return; } +static inline int dma_buf_begin_cpu_access(struct dma_buf *, + size_t, size_t, + enum dma_data_direction) +{ + return -ENODEV; +} + +static inline void dma_buf_end_cpu_access(struct dma_buf *, + size_t, size_t, + enum dma_data_direction) +{ +} + +static inline void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long) +{ + return NULL; +} + +static inline void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, + void *) +{ +} + +static inline void *dma_buf_kmap(struct dma_buf *, unsigned long) +{ + return NULL; +} + +static inline void dma_buf_kunmap(struct dma_buf *, unsigned long, + void *) +{ +} #endif /* CONFIG_DMA_SHARED_BUFFER */ #endif /* __DMA_BUF_H__ */ -- cgit From 3e0b2a1993c06e646d90d71e163d03869a211a4c Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Mon, 26 Mar 2012 11:29:19 +0530 Subject: dma-buf: correct dummy function declarations. Dummy functions for the newly added cpu access ops need variable names for arguments. Also, the introduction of flags in dma_buf_fd needs to be added to dummy functions as well. Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal --- include/linux/dma-buf.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'include/linux/dma-buf.h') diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index ee7ef9990d9a..f141745a13bf 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -188,7 +188,7 @@ static inline struct dma_buf *dma_buf_export(void *priv, return ERR_PTR(-ENODEV); } -static inline int dma_buf_fd(struct dma_buf *dmabuf) +static inline int dma_buf_fd(struct dma_buf *dmabuf, int flags) { return -ENODEV; } @@ -215,36 +215,37 @@ static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, return; } -static inline int dma_buf_begin_cpu_access(struct dma_buf *, - size_t, size_t, - enum dma_data_direction) +static inline int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + size_t start, size_t len, + enum dma_data_direction dir) { return -ENODEV; } -static inline void dma_buf_end_cpu_access(struct dma_buf *, - size_t, size_t, - enum dma_data_direction) +static inline void dma_buf_end_cpu_access(struct dma_buf *dmabuf, + size_t start, size_t len, + enum dma_data_direction dir) { } -static inline void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long) +static inline void *dma_buf_kmap_atomic(struct dma_buf *dmabuf, + unsigned long pnum) { return NULL; } -static inline void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, - void *) +static inline void dma_buf_kunmap_atomic(struct dma_buf *dmabuf, + unsigned long pnum, void *vaddr) { } -static inline void *dma_buf_kmap(struct dma_buf *, unsigned long) +static inline void *dma_buf_kmap(struct dma_buf *dmabuf, unsigned long pnum) { return NULL; } -static inline void dma_buf_kunmap(struct dma_buf *, unsigned long, - void *) +static inline void dma_buf_kunmap(struct dma_buf *dmabuf, + unsigned long pnum, void *vaddr) { } #endif /* CONFIG_DMA_SHARED_BUFFER */ -- cgit