dma-buf: Reorganize device dma access docs
- Put the initial overview for dma-buf into dma-buf.rst. - Put all the comments about detailed semantics into the right kernel-doc comment for functions or ops structure member. - To allow that detail, switch the reworked kerneldoc to inline style for dma_buf_ops. - Tie everything together into a much more streamlined overview comment, relying on the hyperlinks for all the details. - Also sprinkle some links into the kerneldoc for dma_buf and dma_buf_attachment to tie it all together. Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet <corbet@lwn.net> Cc: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: http://patchwork.freedesktop.org/patch/msgid/20161209185309.1682-4-daniel.vetter@ffwll.ch
This commit is contained in:
parent
24a367348a
commit
2904a8c131
|
@ -5,228 +5,6 @@
|
|||
<sumit dot semwal at linaro dot org>
|
||||
<sumit dot semwal at ti dot com>
|
||||
|
||||
This document serves as a guide to device-driver writers on what is the dma-buf
|
||||
buffer sharing API, how to use it for exporting and using shared buffers.
|
||||
|
||||
Any device driver which wishes to be a part of DMA buffer sharing, can do so as
|
||||
either the 'exporter' of buffers, or the 'user' of buffers.
|
||||
|
||||
Say a driver A wants to use buffers created by driver B, then we call B as the
|
||||
exporter, and A as buffer-user.
|
||||
|
||||
The exporter
|
||||
- implements and manages operations[1] for the buffer
|
||||
- allows other users to share the buffer by using dma_buf sharing APIs,
|
||||
- manages the details of buffer allocation,
|
||||
- decides about the actual backing storage where this allocation happens,
|
||||
- takes care of any migration of scatterlist - for all (shared) users of this
|
||||
buffer,
|
||||
|
||||
The buffer-user
|
||||
- is one of (many) sharing users of the buffer.
|
||||
- doesn't need to worry about how the buffer is allocated, or where.
|
||||
- needs a mechanism to get access to the scatterlist that makes up this buffer
|
||||
in memory, mapped into its own address space, so it can access the same area
|
||||
of memory.
|
||||
|
||||
dma-buf operations for device dma only
|
||||
--------------------------------------
|
||||
|
||||
The dma_buf buffer sharing API usage contains the following steps:
|
||||
|
||||
1. Exporter announces that it wishes to export a buffer
|
||||
2. Userspace gets the file descriptor associated with the exported buffer, and
|
||||
passes it around to potential buffer-users based on use case
|
||||
3. Each buffer-user 'connects' itself to the buffer
|
||||
4. When needed, buffer-user requests access to the buffer from exporter
|
||||
5. When finished with its use, the buffer-user notifies end-of-DMA to exporter
|
||||
6. when buffer-user is done using this buffer completely, it 'disconnects'
|
||||
itself from the buffer.
|
||||
|
||||
|
||||
1. Exporter's announcement of buffer export
|
||||
|
||||
The buffer exporter announces its wish to export a buffer. In this, it
|
||||
connects its own private buffer data, provides implementation for operations
|
||||
that can be performed on the exported dma_buf, and flags for the file
|
||||
associated with this buffer. All these fields are filled in struct
|
||||
dma_buf_export_info, defined via the DEFINE_DMA_BUF_EXPORT_INFO macro.
|
||||
|
||||
Interface:
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info)
|
||||
struct dma_buf *dma_buf_export(struct dma_buf_export_info *exp_info)
|
||||
|
||||
If this succeeds, dma_buf_export allocates a dma_buf structure, and
|
||||
returns a pointer to the same. It also associates an anonymous file with this
|
||||
buffer, so it can be exported. On failure to allocate the dma_buf object,
|
||||
it returns NULL.
|
||||
|
||||
'exp_name' in struct dma_buf_export_info is the name of exporter - to
|
||||
facilitate information while debugging. It is set to KBUILD_MODNAME by
|
||||
default, so exporters don't have to provide a specific name, if they don't
|
||||
wish to.
|
||||
|
||||
DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct dma_buf_export_info,
|
||||
zeroes it out and pre-populates exp_name in it.
|
||||
|
||||
|
||||
2. Userspace gets a handle to pass around to potential buffer-users
|
||||
|
||||
Userspace entity requests for a file-descriptor (fd) which is a handle to the
|
||||
anonymous file associated with the buffer. It can then share the fd with other
|
||||
drivers and/or processes.
|
||||
|
||||
Interface:
|
||||
int dma_buf_fd(struct dma_buf *dmabuf, int flags)
|
||||
|
||||
This API installs an fd for the anonymous file associated with this buffer;
|
||||
returns either 'fd', or error.
|
||||
|
||||
3. Each buffer-user 'connects' itself to the buffer
|
||||
|
||||
Each buffer-user now gets a reference to the buffer, using the fd passed to
|
||||
it.
|
||||
|
||||
Interface:
|
||||
struct dma_buf *dma_buf_get(int fd)
|
||||
|
||||
This API will return a reference to the dma_buf, and increment refcount for
|
||||
it.
|
||||
|
||||
After this, the buffer-user needs to attach its device with the buffer, which
|
||||
helps the exporter to know of device buffer constraints.
|
||||
|
||||
Interface:
|
||||
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct device *dev)
|
||||
|
||||
This API returns reference to an attachment structure, which is then used
|
||||
for scatterlist operations. It will optionally call the 'attach' dma_buf
|
||||
operation, if provided by the exporter.
|
||||
|
||||
The dma-buf sharing framework does the bookkeeping bits related to managing
|
||||
the list of all attachments to a buffer.
|
||||
|
||||
Until this stage, the buffer-exporter has the option to choose not to actually
|
||||
allocate the backing storage for this buffer, but wait for the first buffer-user
|
||||
to request use of buffer for allocation.
|
||||
|
||||
|
||||
4. When needed, buffer-user requests access to the buffer
|
||||
|
||||
Whenever a buffer-user wants to use the buffer for any DMA, it asks for
|
||||
access to the buffer using dma_buf_map_attachment API. At least one attach to
|
||||
the buffer must have happened before map_dma_buf can be called.
|
||||
|
||||
Interface:
|
||||
struct sg_table * dma_buf_map_attachment(struct dma_buf_attachment *,
|
||||
enum dma_data_direction);
|
||||
|
||||
This is a wrapper to dma_buf->ops->map_dma_buf operation, which hides the
|
||||
"dma_buf->ops->" indirection from the users of this interface.
|
||||
|
||||
In struct dma_buf_ops, map_dma_buf is defined as
|
||||
struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *,
|
||||
enum dma_data_direction);
|
||||
|
||||
It is one of the buffer operations that must be implemented by the exporter.
|
||||
It should return the sg_table containing scatterlist for this buffer, mapped
|
||||
into caller's address space.
|
||||
|
||||
If this is being called for the first time, the exporter can now choose to
|
||||
scan through the list of attachments for this buffer, collate the requirements
|
||||
of the attached devices, and choose an appropriate backing storage for the
|
||||
buffer.
|
||||
|
||||
Based on enum dma_data_direction, it might be possible to have multiple users
|
||||
accessing at the same time (for reading, maybe), or any other kind of sharing
|
||||
that the exporter might wish to make available to buffer-users.
|
||||
|
||||
map_dma_buf() operation can return -EINTR if it is interrupted by a signal.
|
||||
|
||||
|
||||
5. When finished, the buffer-user notifies end-of-DMA to exporter
|
||||
|
||||
Once the DMA for the current buffer-user is over, it signals 'end-of-DMA' to
|
||||
the exporter using the dma_buf_unmap_attachment API.
|
||||
|
||||
Interface:
|
||||
void dma_buf_unmap_attachment(struct dma_buf_attachment *,
|
||||
struct sg_table *);
|
||||
|
||||
This is a wrapper to dma_buf->ops->unmap_dma_buf() operation, which hides the
|
||||
"dma_buf->ops->" indirection from the users of this interface.
|
||||
|
||||
In struct dma_buf_ops, unmap_dma_buf is defined as
|
||||
void (*unmap_dma_buf)(struct dma_buf_attachment *,
|
||||
struct sg_table *,
|
||||
enum dma_data_direction);
|
||||
|
||||
unmap_dma_buf signifies the end-of-DMA for the attachment provided. Like
|
||||
map_dma_buf, this API also must be implemented by the exporter.
|
||||
|
||||
|
||||
6. when buffer-user is done using this buffer, it 'disconnects' itself from the
|
||||
buffer.
|
||||
|
||||
After the buffer-user has no more interest in using this buffer, it should
|
||||
disconnect itself from the buffer:
|
||||
|
||||
- it first detaches itself from the buffer.
|
||||
|
||||
Interface:
|
||||
void dma_buf_detach(struct dma_buf *dmabuf,
|
||||
struct dma_buf_attachment *dmabuf_attach);
|
||||
|
||||
This API removes the attachment from the list in dmabuf, and optionally calls
|
||||
dma_buf->ops->detach(), if provided by exporter, for any housekeeping bits.
|
||||
|
||||
- Then, the buffer-user returns the buffer reference to exporter.
|
||||
|
||||
Interface:
|
||||
void dma_buf_put(struct dma_buf *dmabuf);
|
||||
|
||||
This API then reduces the refcount for this buffer.
|
||||
|
||||
If, as a result of this call, the refcount becomes 0, the 'release' file
|
||||
operation related to this fd is called. It calls the dmabuf->ops->release()
|
||||
operation in turn, and frees the memory allocated for dmabuf when exported.
|
||||
|
||||
NOTES:
|
||||
- Importance of attach-detach and {map,unmap}_dma_buf operation pairs
|
||||
The attach-detach calls allow the exporter to figure out backing-storage
|
||||
constraints for the currently-interested devices. This allows preferential
|
||||
allocation, and/or migration of pages across different types of storage
|
||||
available, if possible.
|
||||
|
||||
Bracketing of DMA access with {map,unmap}_dma_buf operations is essential
|
||||
to allow just-in-time backing of storage, and migration mid-way through a
|
||||
use-case.
|
||||
|
||||
- Migration of backing storage if needed
|
||||
If after
|
||||
- at least one map_dma_buf has happened,
|
||||
- and the backing storage has been allocated for this buffer,
|
||||
another new buffer-user intends to attach itself to this buffer, it might
|
||||
be allowed, if possible for the exporter.
|
||||
|
||||
In case it is allowed by the exporter:
|
||||
if the new buffer-user has stricter 'backing-storage constraints', and the
|
||||
exporter can handle these constraints, the exporter can just stall on the
|
||||
map_dma_buf until all outstanding access is completed (as signalled by
|
||||
unmap_dma_buf).
|
||||
Once all users have finished accessing and have unmapped this buffer, the
|
||||
exporter could potentially move the buffer to the stricter backing-storage,
|
||||
and then allow further {map,unmap}_dma_buf operations from any buffer-user
|
||||
from the migrated backing-storage.
|
||||
|
||||
If the exporter cannot fulfill the backing-storage constraints of the new
|
||||
buffer-user device as requested, dma_buf_attach() would return an error to
|
||||
denote non-compatibility of the new buffer-sharing request with the current
|
||||
buffer.
|
||||
|
||||
If the exporter chooses not to allow an attach() operation once a
|
||||
map_dma_buf() API has been called, it simply returns an error.
|
||||
|
||||
Kernel cpu access to a dma-buf buffer object
|
||||
--------------------------------------------
|
||||
|
|
|
@ -17,6 +17,44 @@ shared or exclusive fence(s) associated with the buffer.
|
|||
Shared DMA Buffers
|
||||
------------------
|
||||
|
||||
This document serves as a guide to device-driver writers on what is the dma-buf
|
||||
buffer sharing API, how to use it for exporting and using shared buffers.
|
||||
|
||||
Any device driver which wishes to be a part of DMA buffer sharing, can do so as
|
||||
either the 'exporter' of buffers, or the 'user' or 'importer' of buffers.
|
||||
|
||||
Say a driver A wants to use buffers created by driver B, then we call B as the
|
||||
exporter, and A as buffer-user/importer.
|
||||
|
||||
The exporter
|
||||
|
||||
- implements and manages operations in :c:type:`struct dma_buf_ops
|
||||
<dma_buf_ops>` for the buffer,
|
||||
- allows other users to share the buffer by using dma_buf sharing APIs,
|
||||
- manages the details of buffer allocation, wrapped int a :c:type:`struct
|
||||
dma_buf <dma_buf>`,
|
||||
- decides about the actual backing storage where this allocation happens,
|
||||
- and takes care of any migration of scatterlist - for all (shared) users of
|
||||
this buffer.
|
||||
|
||||
The buffer-user
|
||||
|
||||
- is one of (many) sharing users of the buffer.
|
||||
- doesn't need to worry about how the buffer is allocated, or where.
|
||||
- and needs a mechanism to get access to the scatterlist that makes up this
|
||||
buffer in memory, mapped into its own address space, so it can access the
|
||||
same area of memory. This interface is provided by :c:type:`struct
|
||||
dma_buf_attachment <dma_buf_attachment>`.
|
||||
|
||||
Basic Operation and Device DMA Access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:doc: dma buf device access
|
||||
|
||||
Kernel Functions and Structures Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:export:
|
||||
|
||||
|
|
|
@ -313,6 +313,37 @@ static inline int is_dma_buf_file(struct file *file)
|
|||
return file->f_op == &dma_buf_fops;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOC: dma buf device access
|
||||
*
|
||||
* For device DMA access to a shared DMA buffer the usual sequence of operations
|
||||
* is fairly simple:
|
||||
*
|
||||
* 1. The exporter defines his exporter instance using
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO() and calls dma_buf_export() to wrap a private
|
||||
* buffer object into a &dma_buf. It then exports that &dma_buf to userspace
|
||||
* as a file descriptor by calling dma_buf_fd().
|
||||
*
|
||||
* 2. Userspace passes this file-descriptors to all drivers it wants this buffer
|
||||
* to share with: First the filedescriptor is converted to a &dma_buf using
|
||||
* dma_buf_get(). The the buffer is attached to the device using
|
||||
* dma_buf_attach().
|
||||
*
|
||||
* Up to this stage the exporter is still free to migrate or reallocate the
|
||||
* backing storage.
|
||||
*
|
||||
* 3. Once the buffer is attached to all devices userspace can inniate DMA
|
||||
* access to the shared buffer. In the kernel this is done by calling
|
||||
* dma_buf_map_attachment() and dma_buf_unmap_attachment().
|
||||
*
|
||||
* 4. Once a driver is done with a shared buffer it needs to call
|
||||
* dma_buf_detach() (after cleaning up any mappings) and then release the
|
||||
* reference acquired with dma_buf_get by calling dma_buf_put().
|
||||
*
|
||||
* For the detailed semantics exporters are expected to implement see
|
||||
* &dma_buf_ops.
|
||||
*/
|
||||
|
||||
/**
|
||||
* dma_buf_export - Creates a new dma_buf, and associates an anon file
|
||||
* with this buffer, so it can be exported.
|
||||
|
@ -320,13 +351,15 @@ static inline int is_dma_buf_file(struct file *file)
|
|||
* Additionally, provide a name string for exporter; useful in debugging.
|
||||
*
|
||||
* @exp_info: [in] holds all the export related information provided
|
||||
* by the exporter. see struct dma_buf_export_info
|
||||
* by the exporter. see struct &dma_buf_export_info
|
||||
* for further details.
|
||||
*
|
||||
* Returns, on success, a newly created dma_buf object, which wraps the
|
||||
* supplied private data and operations for dma_buf_ops. On either missing
|
||||
* ops, or error in allocating struct dma_buf, will return negative error.
|
||||
*
|
||||
* For most cases the easiest way to create @exp_info is through the
|
||||
* %DEFINE_DMA_BUF_EXPORT_INFO macro.
|
||||
*/
|
||||
struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
{
|
||||
|
@ -458,7 +491,12 @@ EXPORT_SYMBOL_GPL(dma_buf_get);
|
|||
* dma_buf_put - decreases refcount of the buffer
|
||||
* @dmabuf: [in] buffer to reduce refcount of
|
||||
*
|
||||
* Uses file's refcounting done implicitly by fput()
|
||||
* Uses file's refcounting done implicitly by fput().
|
||||
*
|
||||
* If, as a result of this call, the refcount becomes 0, the 'release' file
|
||||
* operation related to this fd is called. It calls the release operation of
|
||||
* struct &dma_buf_ops in turn, and frees the memory allocated for dmabuf when
|
||||
* exported.
|
||||
*/
|
||||
void dma_buf_put(struct dma_buf *dmabuf)
|
||||
{
|
||||
|
@ -475,8 +513,17 @@ EXPORT_SYMBOL_GPL(dma_buf_put);
|
|||
* @dmabuf: [in] buffer to attach device to.
|
||||
* @dev: [in] device to be attached.
|
||||
*
|
||||
* Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on
|
||||
* error.
|
||||
* Returns struct dma_buf_attachment pointer for this attachment. Attachments
|
||||
* must be cleaned up by calling dma_buf_detach().
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* A pointer to newly created &dma_buf_attachment on success, or a negative
|
||||
* error code wrapped into a pointer on failure.
|
||||
*
|
||||
* Note that this can fail if the backing storage of @dmabuf is in a place not
|
||||
* accessible to @dev, and cannot be moved to a more suitable place. This is
|
||||
* indicated with the error code -EBUSY.
|
||||
*/
|
||||
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct device *dev)
|
||||
|
@ -519,6 +566,7 @@ EXPORT_SYMBOL_GPL(dma_buf_attach);
|
|||
* @dmabuf: [in] buffer to detach from.
|
||||
* @attach: [in] attachment to be detached; is free'd after this call.
|
||||
*
|
||||
* Clean up a device attachment obtained by calling dma_buf_attach().
|
||||
*/
|
||||
void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
|
||||
{
|
||||
|
@ -543,7 +591,12 @@ EXPORT_SYMBOL_GPL(dma_buf_detach);
|
|||
* @direction: [in] direction of DMA transfer
|
||||
*
|
||||
* Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
|
||||
* on error.
|
||||
* on error. May return -EINTR if it is interrupted by a signal.
|
||||
*
|
||||
* A mapping must be unmapped again using dma_buf_map_attachment(). Note that
|
||||
* the underlying backing storage is pinned for as long as a mapping exists,
|
||||
* therefore users/importers should not hold onto a mapping for undue amounts of
|
||||
* time.
|
||||
*/
|
||||
struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
enum dma_data_direction direction)
|
||||
|
@ -571,6 +624,7 @@ EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
|
|||
* @sg_table: [in] scatterlist info of the buffer to unmap
|
||||
* @direction: [in] direction of DMA transfer
|
||||
*
|
||||
* This unmaps a DMA mapping for @attached obtained by dma_buf_map_attachment().
|
||||
*/
|
||||
void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
|
||||
struct sg_table *sg_table,
|
||||
|
|
|
@ -462,4 +462,3 @@ static const struct file_operations sync_file_fops = {
|
|||
.unlocked_ioctl = sync_file_ioctl,
|
||||
.compat_ioctl = sync_file_ioctl,
|
||||
};
|
||||
|
||||
|
|
|
@ -39,19 +39,6 @@ struct dma_buf_attachment;
|
|||
|
||||
/**
|
||||
* struct dma_buf_ops - operations possible on struct dma_buf
|
||||
* @attach: [optional] allows different devices to 'attach' themselves to the
|
||||
* given buffer. It might return -EBUSY to signal that backing storage
|
||||
* is already allocated and incompatible with the requirements
|
||||
* of requesting device.
|
||||
* @detach: [optional] detach a given device from this buffer.
|
||||
* @map_dma_buf: returns list of scatter pages allocated, increases usecount
|
||||
* of the buffer. Requires atleast one attach to be called
|
||||
* before. Returned sg list should already be mapped into
|
||||
* _device_ address space. This call may sleep. May also return
|
||||
* -EINTR. Should return -EINVAL if attach hasn't been called yet.
|
||||
* @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 object into memory.
|
||||
|
@ -72,25 +59,109 @@ struct dma_buf_attachment;
|
|||
* @vunmap: [optional] unmaps a vmap from the buffer
|
||||
*/
|
||||
struct dma_buf_ops {
|
||||
/**
|
||||
* @attach:
|
||||
*
|
||||
* This is called from dma_buf_attach() to make sure that a given
|
||||
* &device can access the provided &dma_buf. Exporters which support
|
||||
* buffer objects in special locations like VRAM or device-specific
|
||||
* carveout areas should check whether the buffer could be move to
|
||||
* system memory (or directly accessed by the provided device), and
|
||||
* otherwise need to fail the attach operation.
|
||||
*
|
||||
* The exporter should also in general check whether the current
|
||||
* allocation fullfills the DMA constraints of the new device. If this
|
||||
* is not the case, and the allocation cannot be moved, it should also
|
||||
* fail the attach operation.
|
||||
*
|
||||
* Any exporter-private housekeeping data can be stored in the priv
|
||||
* pointer of &dma_buf_attachment structure.
|
||||
*
|
||||
* This callback is optional.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 on success, negative error code on failure. It might return -EBUSY
|
||||
* to signal that backing storage is already allocated and incompatible
|
||||
* with the requirements of requesting device.
|
||||
*/
|
||||
int (*attach)(struct dma_buf *, struct device *,
|
||||
struct dma_buf_attachment *);
|
||||
|
||||
/**
|
||||
* @detach:
|
||||
*
|
||||
* This is called by dma_buf_detach() to release a &dma_buf_attachment.
|
||||
* Provided so that exporters can clean up any housekeeping for an
|
||||
* &dma_buf_attachment.
|
||||
*
|
||||
* This callback is optional.
|
||||
*/
|
||||
void (*detach)(struct dma_buf *, struct dma_buf_attachment *);
|
||||
|
||||
/* For {map,unmap}_dma_buf below, any specific buffer attributes
|
||||
* required should get added to device_dma_parameters accessible
|
||||
* via dev->dma_params.
|
||||
/**
|
||||
* @map_dma_buf:
|
||||
*
|
||||
* This is called by dma_buf_map_attachment() and is used to map a
|
||||
* shared &dma_buf into device address space, and it is mandatory. It
|
||||
* can only be called if @attach has been called successfully. This
|
||||
* essentially pins the DMA buffer into place, and it cannot be moved
|
||||
* any more
|
||||
*
|
||||
* This call may sleep, e.g. when the backing storage first needs to be
|
||||
* allocated, or moved to a location suitable for all currently attached
|
||||
* devices.
|
||||
*
|
||||
* Note that any specific buffer attributes required for this function
|
||||
* should get added to device_dma_parameters accessible via
|
||||
* device->dma_params from the &dma_buf_attachment. The @attach callback
|
||||
* should also check these constraints.
|
||||
*
|
||||
* If this is being called for the first time, the exporter can now
|
||||
* choose to scan through the list of attachments for this buffer,
|
||||
* collate the requirements of the attached devices, and choose an
|
||||
* appropriate backing storage for the buffer.
|
||||
*
|
||||
* Based on enum dma_data_direction, it might be possible to have
|
||||
* multiple users accessing at the same time (for reading, maybe), or
|
||||
* any other kind of sharing that the exporter might wish to make
|
||||
* available to buffer-users.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* A &sg_table scatter list of or the backing storage of the DMA buffer,
|
||||
* already mapped into the device address space of the &device attached
|
||||
* with the provided &dma_buf_attachment.
|
||||
*
|
||||
* On failure, returns a negative error value wrapped into a pointer.
|
||||
* May also return -EINTR when a signal was received while being
|
||||
* blocked.
|
||||
*/
|
||||
struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *,
|
||||
enum dma_data_direction);
|
||||
/**
|
||||
* @unmap_dma_buf:
|
||||
*
|
||||
* This is called by dma_buf_unmap_attachment() and should unmap and
|
||||
* release the &sg_table allocated in @map_dma_buf, and it is mandatory.
|
||||
* It should also unpin the backing storage if this is the last mapping
|
||||
* of the DMA buffer, it the exporter supports backing storage
|
||||
* migration.
|
||||
*/
|
||||
void (*unmap_dma_buf)(struct dma_buf_attachment *,
|
||||
struct sg_table *,
|
||||
enum dma_data_direction);
|
||||
|
||||
/* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
|
||||
* if the call would block.
|
||||
*/
|
||||
|
||||
/* after final dma_buf_put() */
|
||||
/**
|
||||
* @release:
|
||||
*
|
||||
* Called after the last dma_buf_put to release the &dma_buf, and
|
||||
* mandatory.
|
||||
*/
|
||||
void (*release)(struct dma_buf *);
|
||||
|
||||
int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction);
|
||||
|
@ -124,6 +195,15 @@ struct dma_buf_ops {
|
|||
* @poll: for userspace poll support
|
||||
* @cb_excl: for userspace poll support
|
||||
* @cb_shared: for userspace poll support
|
||||
*
|
||||
* This represents a shared buffer, created by calling dma_buf_export(). The
|
||||
* userspace representation is a normal file descriptor, which can be created by
|
||||
* calling dma_buf_fd().
|
||||
*
|
||||
* Shared dma buffers are reference counted using dma_buf_put() and
|
||||
* get_dma_buf().
|
||||
*
|
||||
* Device DMA access is handled by the separate struct &dma_buf_attachment.
|
||||
*/
|
||||
struct dma_buf {
|
||||
size_t size;
|
||||
|
@ -160,6 +240,11 @@ struct dma_buf {
|
|||
* This structure holds the attachment information between the dma_buf buffer
|
||||
* and its user device(s). The list contains one attachment struct per device
|
||||
* attached to the buffer.
|
||||
*
|
||||
* An attachment is created by calling dma_buf_attach(), and released again by
|
||||
* calling dma_buf_detach(). The DMA mapping itself needed to initiate a
|
||||
* transfer is created by dma_buf_map_attachment() and freed again by calling
|
||||
* dma_buf_unmap_attachment().
|
||||
*/
|
||||
struct dma_buf_attachment {
|
||||
struct dma_buf *dmabuf;
|
||||
|
@ -192,9 +277,11 @@ struct dma_buf_export_info {
|
|||
};
|
||||
|
||||
/**
|
||||
* helper macro for exporters; zeros and fills in most common values
|
||||
*
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO - helper macro for exporters
|
||||
* @name: export-info name
|
||||
*
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct &dma_buf_export_info,
|
||||
* zeroes it out and pre-populates exp_name in it.
|
||||
*/
|
||||
#define DEFINE_DMA_BUF_EXPORT_INFO(name) \
|
||||
struct dma_buf_export_info name = { .exp_name = KBUILD_MODNAME, \
|
||||
|
|
Loading…
Reference in New Issue