* 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];
};
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))
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,
{
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_ */
#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;
}
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
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_ */