xref: /openbmc/linux/drivers/virtio/virtio_dma_buf.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1a0308938SDavid Stevens // SPDX-License-Identifier: GPL-2.0-or-later
2a0308938SDavid Stevens /*
3a0308938SDavid Stevens  * dma-bufs for virtio exported objects
4a0308938SDavid Stevens  *
5a0308938SDavid Stevens  * Copyright (C) 2020 Google, Inc.
6a0308938SDavid Stevens  */
7a0308938SDavid Stevens 
89fe2f897SDavid Stevens #include <linux/module.h>
9a0308938SDavid Stevens #include <linux/virtio_dma_buf.h>
10a0308938SDavid Stevens 
11a0308938SDavid Stevens /**
12a0308938SDavid Stevens  * virtio_dma_buf_export - Creates a new dma-buf for a virtio exported object
13a0308938SDavid Stevens  * @exp_info: [in] see dma_buf_export(). ops MUST refer to a dma_buf_ops
14a0308938SDavid Stevens  *	struct embedded in a virtio_dma_buf_ops.
15a0308938SDavid Stevens  *
16a0308938SDavid Stevens  * This wraps dma_buf_export() to allow virtio drivers to create a dma-buf
17a0308938SDavid Stevens  * for an virtio exported object that can be queried by other virtio drivers
18a0308938SDavid Stevens  * for the object's UUID.
19a0308938SDavid Stevens  */
virtio_dma_buf_export(const struct dma_buf_export_info * exp_info)20a0308938SDavid Stevens struct dma_buf *virtio_dma_buf_export
21a0308938SDavid Stevens 	(const struct dma_buf_export_info *exp_info)
22a0308938SDavid Stevens {
23a0308938SDavid Stevens 	const struct virtio_dma_buf_ops *virtio_ops =
24a0308938SDavid Stevens 		container_of(exp_info->ops,
25a0308938SDavid Stevens 			     const struct virtio_dma_buf_ops, ops);
26a0308938SDavid Stevens 
27a0308938SDavid Stevens 	if (!exp_info->ops ||
28a0308938SDavid Stevens 	    exp_info->ops->attach != &virtio_dma_buf_attach ||
29a0308938SDavid Stevens 	    !virtio_ops->get_uuid) {
30a0308938SDavid Stevens 		return ERR_PTR(-EINVAL);
31a0308938SDavid Stevens 	}
32a0308938SDavid Stevens 
33a0308938SDavid Stevens 	return dma_buf_export(exp_info);
34a0308938SDavid Stevens }
35a0308938SDavid Stevens EXPORT_SYMBOL(virtio_dma_buf_export);
36a0308938SDavid Stevens 
37a0308938SDavid Stevens /**
38a0308938SDavid Stevens  * virtio_dma_buf_attach - mandatory attach callback for virtio dma-bufs
39a0308938SDavid Stevens  */
virtio_dma_buf_attach(struct dma_buf * dma_buf,struct dma_buf_attachment * attach)40a0308938SDavid Stevens int virtio_dma_buf_attach(struct dma_buf *dma_buf,
41a0308938SDavid Stevens 			  struct dma_buf_attachment *attach)
42a0308938SDavid Stevens {
43a0308938SDavid Stevens 	int ret;
44a0308938SDavid Stevens 	const struct virtio_dma_buf_ops *ops =
45a0308938SDavid Stevens 		container_of(dma_buf->ops,
46a0308938SDavid Stevens 			     const struct virtio_dma_buf_ops, ops);
47a0308938SDavid Stevens 
48a0308938SDavid Stevens 	if (ops->device_attach) {
49a0308938SDavid Stevens 		ret = ops->device_attach(dma_buf, attach);
50a0308938SDavid Stevens 		if (ret)
51a0308938SDavid Stevens 			return ret;
52a0308938SDavid Stevens 	}
53a0308938SDavid Stevens 	return 0;
54a0308938SDavid Stevens }
55a0308938SDavid Stevens EXPORT_SYMBOL(virtio_dma_buf_attach);
56a0308938SDavid Stevens 
57a0308938SDavid Stevens /**
58a0308938SDavid Stevens  * is_virtio_dma_buf - returns true if the given dma-buf is a virtio dma-buf
59a0308938SDavid Stevens  * @dma_buf: buffer to query
60a0308938SDavid Stevens  */
is_virtio_dma_buf(struct dma_buf * dma_buf)61a0308938SDavid Stevens bool is_virtio_dma_buf(struct dma_buf *dma_buf)
62a0308938SDavid Stevens {
63a0308938SDavid Stevens 	return dma_buf->ops->attach == &virtio_dma_buf_attach;
64a0308938SDavid Stevens }
65a0308938SDavid Stevens EXPORT_SYMBOL(is_virtio_dma_buf);
66a0308938SDavid Stevens 
67a0308938SDavid Stevens /**
68a0308938SDavid Stevens  * virtio_dma_buf_get_uuid - gets a virtio dma-buf's exported object's uuid
69a0308938SDavid Stevens  * @dma_buf: [in] buffer to query
70a0308938SDavid Stevens  * @uuid: [out] the uuid
71a0308938SDavid Stevens  *
72a0308938SDavid Stevens  * Returns: 0 on success, negative on failure.
73a0308938SDavid Stevens  */
virtio_dma_buf_get_uuid(struct dma_buf * dma_buf,uuid_t * uuid)74a0308938SDavid Stevens int virtio_dma_buf_get_uuid(struct dma_buf *dma_buf,
75a0308938SDavid Stevens 			    uuid_t *uuid)
76a0308938SDavid Stevens {
77a0308938SDavid Stevens 	const struct virtio_dma_buf_ops *ops =
78a0308938SDavid Stevens 		container_of(dma_buf->ops,
79a0308938SDavid Stevens 			     const struct virtio_dma_buf_ops, ops);
80a0308938SDavid Stevens 
81a0308938SDavid Stevens 	if (!is_virtio_dma_buf(dma_buf))
82a0308938SDavid Stevens 		return -EINVAL;
83a0308938SDavid Stevens 
84a0308938SDavid Stevens 	return ops->get_uuid(dma_buf, uuid);
85a0308938SDavid Stevens }
86a0308938SDavid Stevens EXPORT_SYMBOL(virtio_dma_buf_get_uuid);
879fe2f897SDavid Stevens 
889fe2f897SDavid Stevens MODULE_LICENSE("GPL");
89*16b0314aSGreg Kroah-Hartman MODULE_IMPORT_NS(DMA_BUF);
90