dma-buf: add buffer mask to dma-buf container
authorCho KyongHo <pullip.cho@samsung.com>
Wed, 18 Apr 2018 13:24:20 +0000 (22:24 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:20 +0000 (20:22 +0300)
Mask of dma-buf container is a bit-mask of buffers in the dma-buf
container. The bit order in the mask is the position of buffers in
the dma-buf container. LSB of the mask is the bit-mask of the buffer
0 in the dma-buf container.
The mask of a dma-buf container is zero on creation. This means that
all buffers in the dma-buf container are unmasked initially. Users
of dma-buf container can modify the mask of buffers later with the
following API functions/ioctl of dma-buf.
- dmabuf_container_set_mask()
- dmabuf_container_get_mask()
- DMA_BUF_IOCTL_CONTAINER_SET_MASK
- DMA_BUF_IOCTL_CONTAINER_GET_MASK

The mask of dma-buf container is not used by dma-buf container itself.
How to use the mask is entirely rely on the users. Users can configure
the activation information of buffers of a dma-buf container. Others
may use the mask to indicate buffers with special information.

Change-Id: I2cc7d68812c060ed4fabb50da89271d52ad01ddc
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/dma-buf/dma-buf-container.c
drivers/dma-buf/dma-buf-container.h
drivers/dma-buf/dma-buf.c
include/linux/dma-buf-container.h
include/uapi/linux/dma-buf.h

index f76500240739ed181f64ed751eb8d6001f6a3062..ec5ef43ec2779ffb1627b9fb585e056557866ebe 100644 (file)
@@ -108,11 +108,14 @@ static int dmabuf_container_put_user_data(unsigned int cmd, void __user *arg,
  * struct dma_buf_container - container description
  * @table:     dummy sg_table for container
  * @count:     the number of the buffers
+ * @dmabuf_mask: bit-mask of dma-bufs in @dmabufs.
+ *               @dmabuf_mask is 0(unmasked) on creation of a dma-buf container.
  * @dmabufs:   dmabuf array representing each buffers
  */
 struct dma_buf_container {
        struct sg_table table;
        int             count;
+       u32             dmabuf_mask;
        struct dma_buf  *dmabufs[0];
 };
 
@@ -313,6 +316,71 @@ long dma_buf_merge_ioctl(struct dma_buf *dmabuf,
        return 0;
 }
 
+int dmabuf_container_set_mask_user(struct dma_buf *dmabuf, unsigned long arg)
+{
+       u32 mask;
+
+       if (get_user(mask, (u32 __user *)arg)) {
+               pr_err("%s: failed to read mask from user\n", __func__);
+               return -EFAULT;
+       }
+
+       return dmabuf_container_set_mask(dmabuf, mask);
+}
+
+int dmabuf_container_get_mask_user(struct dma_buf *dmabuf, unsigned long arg)
+{
+       u32 mask;
+       int ret;
+
+       ret = dmabuf_container_get_mask(dmabuf, &mask);
+       if (ret < 0)
+               return ret;
+
+       if (put_user(mask, (u32 __user *)arg)) {
+               pr_err("%s: failed to write mask to user\n", __func__);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask)
+{
+       struct dma_buf_container *container;
+
+       if (!is_dmabuf_container(dmabuf)) {
+               pr_err("%s: given dmabuf is not dma-buf container\n", __func__);
+               return -EINVAL;
+       }
+
+       container = get_container(dmabuf);
+
+       if (mask & ~((1 << container->count) - 1)) {
+               pr_err("%s: invalid mask %#x for %u buffers\n",
+                      __func__, mask, container->count);
+               return -EINVAL;
+       }
+
+       get_container(dmabuf)->dmabuf_mask = mask;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dmabuf_container_set_mask);
+
+int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask)
+{
+       if (!is_dmabuf_container(dmabuf)) {
+               pr_err("%s: given dmabuf is not dma-buf container\n", __func__);
+               return -EINVAL;
+       }
+
+       *mask = get_container(dmabuf)->dmabuf_mask;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dmabuf_container_get_mask);
+
 int dmabuf_container_get_count(struct dma_buf *dmabuf)
 {
        if (!is_dmabuf_container(dmabuf))
index efd05d6b9f67511b52910e8d93b8ac7145b10714..e53143374e028d4c5d8666406899ad2a4170bfeb 100644 (file)
@@ -42,6 +42,8 @@ struct dma_buf;
 long dma_buf_merge_ioctl(struct dma_buf *dmabuf,
                         unsigned int cmd, unsigned long arg);
 
+int dmabuf_container_set_mask_user(struct dma_buf *dmabuf, unsigned long arg);
+int dmabuf_container_get_mask_user(struct dma_buf *dmabuf, unsigned long arg);
 #else
 
 static inline long dma_buf_merge_ioctl(struct dma_buf *dmabuf,
@@ -49,6 +51,17 @@ static inline long dma_buf_merge_ioctl(struct dma_buf *dmabuf,
 {
        return -ENOTTY;
 }
+
+static inline int dmabuf_container_set_mask_user(struct dma_buf *dmabuf,
+                                                unsigned long arg)
+{
+       return -ENOTTY;
+}
+static inline int dmabuf_container_get_mask_user(struct dma_buf *dmabuf,
+                                                unsigned long arg)
+{
+       return -ENOTTY;
+}
 #endif
 
 #endif /* _DMA_BUF_CONTAINER_H_ */
index 2da03e86d22c97f22a26255ff1a0638787536f94..92ef63d992e7721ae16e20106bbb20b08b9a1249 100644 (file)
@@ -321,6 +321,10 @@ static long dma_buf_ioctl(struct file *file,
 #endif
        case DMA_BUF_IOCTL_MERGE:
                return dma_buf_merge_ioctl(dmabuf, cmd, arg);
+       case DMA_BUF_IOCTL_CONTAINER_SET_MASK:
+               return dmabuf_container_set_mask_user(dmabuf, arg);
+       case DMA_BUF_IOCTL_CONTAINER_GET_MASK:
+               return dmabuf_container_get_mask_user(dmabuf, arg);
        default:
                return -ENOTTY;
        }
index f0d47299e58dfe83a6c1f9580738de6e01ceb410..f646fc9201f004647309bfe9474822fa97457d31 100644 (file)
@@ -6,6 +6,8 @@
 
 int dmabuf_container_get_count(struct dma_buf *dmabuf);
 struct dma_buf *dmabuf_container_get_buffer(struct dma_buf *dmabuf, int index);
+int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask);
+int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask);
 
 #else
 
@@ -20,6 +22,16 @@ static inline struct dma_buf *dmabuf_container_get_buffer(struct dma_buf *dbuf,
        return NULL;
 }
 
+static inline int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask)
+{
+       return -EINVAL;
+}
+
+static inline int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask)
+{
+       return -EINVAL;
+}
+
 #endif
 
 #endif /* _LINUX_DMA_BUF_CONTAINER_H_ */
index d7dd380d483d99aa8ac5f61fd1e2731b91523d39..489f54c4b8d40f203a8d037f685d8159b52324d8 100644 (file)
@@ -51,5 +51,7 @@ struct dma_buf_merge {
        __u32 reserved[2];
 };
 #define DMA_BUF_IOCTL_MERGE    _IOWR(DMA_BUF_BASE, 13, struct dma_buf_merge)
+#define DMA_BUF_IOCTL_CONTAINER_SET_MASK       _IOW(DMA_BUF_BASE, 14, __u32)
+#define DMA_BUF_IOCTL_CONTAINER_GET_MASK       _IOR(DMA_BUF_BASE, 14, __u32)
 
 #endif