13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 23d0407baSopenharmony_ci/* 33d0407baSopenharmony_ci * Header file for dma buffer sharing framework. 43d0407baSopenharmony_ci * 53d0407baSopenharmony_ci * Copyright(C) 2011 Linaro Limited. All rights reserved. 63d0407baSopenharmony_ci * Author: Sumit Semwal <sumit.semwal@ti.com> 73d0407baSopenharmony_ci * 83d0407baSopenharmony_ci * Many thanks to linaro-mm-sig list, and specially 93d0407baSopenharmony_ci * Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and 103d0407baSopenharmony_ci * Daniel Vetter <daniel@ffwll.ch> for their support in creation and 113d0407baSopenharmony_ci * refining of this idea. 123d0407baSopenharmony_ci */ 133d0407baSopenharmony_ci#ifndef __DMA_BUF_H__ 143d0407baSopenharmony_ci#define __DMA_BUF_H__ 153d0407baSopenharmony_ci 163d0407baSopenharmony_ci#include <linux/file.h> 173d0407baSopenharmony_ci#include <linux/err.h> 183d0407baSopenharmony_ci#include <linux/scatterlist.h> 193d0407baSopenharmony_ci#include <linux/list.h> 203d0407baSopenharmony_ci#include <linux/dma-mapping.h> 213d0407baSopenharmony_ci#include <linux/fs.h> 223d0407baSopenharmony_ci#include <linux/dma-fence.h> 233d0407baSopenharmony_ci#include <linux/wait.h> 243d0407baSopenharmony_ci 253d0407baSopenharmony_cistruct device; 263d0407baSopenharmony_cistruct dma_buf; 273d0407baSopenharmony_cistruct dma_buf_attachment; 283d0407baSopenharmony_ci 293d0407baSopenharmony_ci/** 303d0407baSopenharmony_ci * struct dma_buf_ops - operations possible on struct dma_buf 313d0407baSopenharmony_ci * @vmap: [optional] creates a virtual mapping for the buffer into kernel 323d0407baSopenharmony_ci * address space. Same restrictions as for vmap and friends apply. 333d0407baSopenharmony_ci * @vunmap: [optional] unmaps a vmap from the buffer 343d0407baSopenharmony_ci */ 353d0407baSopenharmony_cistruct dma_buf_ops { 363d0407baSopenharmony_ci /** 373d0407baSopenharmony_ci * @cache_sgt_mapping: 383d0407baSopenharmony_ci * 393d0407baSopenharmony_ci * If true the framework will cache the first mapping made for each 403d0407baSopenharmony_ci * attachment. This avoids creating mappings for attachments multiple 413d0407baSopenharmony_ci * times. 423d0407baSopenharmony_ci */ 433d0407baSopenharmony_ci bool cache_sgt_mapping; 443d0407baSopenharmony_ci 453d0407baSopenharmony_ci /** 463d0407baSopenharmony_ci * @attach 473d0407baSopenharmony_ci * 483d0407baSopenharmony_ci * This is called from dma_buf_attach() to make sure that a given 493d0407baSopenharmony_ci * &dma_buf_attachment.dev can access the provided &dma_buf. Exporters 503d0407baSopenharmony_ci * which support buffer objects in special locations like VRAM or 513d0407baSopenharmony_ci * device-specific carveout areas should check whether the buffer could 523d0407baSopenharmony_ci * be move to system memory (or directly accessed by the provided 533d0407baSopenharmony_ci * device), and otherwise need to fail the attach operation. 543d0407baSopenharmony_ci * 553d0407baSopenharmony_ci * The exporter should also in general check whether the current 563d0407baSopenharmony_ci * allocation fullfills the DMA constraints of the new device. If this 573d0407baSopenharmony_ci * is not the case, and the allocation cannot be moved, it should also 583d0407baSopenharmony_ci * fail the attach operation. 593d0407baSopenharmony_ci * 603d0407baSopenharmony_ci * Any exporter-private housekeeping data can be stored in the 613d0407baSopenharmony_ci * &dma_buf_attachment.priv pointer. 623d0407baSopenharmony_ci * 633d0407baSopenharmony_ci * This callback is optional. 643d0407baSopenharmony_ci * 653d0407baSopenharmony_ci * Returns 663d0407baSopenharmony_ci * 673d0407baSopenharmony_ci * 0 on success, negative error code on failure. It might return -EBUSY 683d0407baSopenharmony_ci * to signal that backing storage is already allocated and incompatible 693d0407baSopenharmony_ci * with the requirements of requesting device. 703d0407baSopenharmony_ci */ 713d0407baSopenharmony_ci int (*attach)(struct dma_buf *, struct dma_buf_attachment *); 723d0407baSopenharmony_ci 733d0407baSopenharmony_ci /** 743d0407baSopenharmony_ci * @detach 753d0407baSopenharmony_ci * 763d0407baSopenharmony_ci * This is called by dma_buf_detach() to release a &dma_buf_attachment. 773d0407baSopenharmony_ci * Provided so that exporters can clean up any housekeeping for an 783d0407baSopenharmony_ci * &dma_buf_attachment. 793d0407baSopenharmony_ci * 803d0407baSopenharmony_ci * This callback is optional. 813d0407baSopenharmony_ci */ 823d0407baSopenharmony_ci void (*detach)(struct dma_buf *, struct dma_buf_attachment *); 833d0407baSopenharmony_ci 843d0407baSopenharmony_ci /** 853d0407baSopenharmony_ci * @pin 863d0407baSopenharmony_ci * 873d0407baSopenharmony_ci * This is called by dma_buf_pin and lets the exporter know that the 883d0407baSopenharmony_ci * DMA-buf can't be moved any more. 893d0407baSopenharmony_ci * 903d0407baSopenharmony_ci * This is called with the dmabuf->resv object locked and is mutual 913d0407baSopenharmony_ci * exclusive with @cache_sgt_mapping. 923d0407baSopenharmony_ci * 933d0407baSopenharmony_ci * This callback is optional and should only be used in limited use 943d0407baSopenharmony_ci * cases like scanout and not for temporary pin operations. 953d0407baSopenharmony_ci * 963d0407baSopenharmony_ci * Returns 973d0407baSopenharmony_ci * 983d0407baSopenharmony_ci * 0 on success, negative error code on failure. 993d0407baSopenharmony_ci */ 1003d0407baSopenharmony_ci int (*pin)(struct dma_buf_attachment *attach); 1013d0407baSopenharmony_ci 1023d0407baSopenharmony_ci /** 1033d0407baSopenharmony_ci * @unpin 1043d0407baSopenharmony_ci * 1053d0407baSopenharmony_ci * This is called by dma_buf_unpin and lets the exporter know that the 1063d0407baSopenharmony_ci * DMA-buf can be moved again. 1073d0407baSopenharmony_ci * 1083d0407baSopenharmony_ci * This is called with the dmabuf->resv object locked and is mutual 1093d0407baSopenharmony_ci * exclusive with @cache_sgt_mapping. 1103d0407baSopenharmony_ci * 1113d0407baSopenharmony_ci * This callback is optional. 1123d0407baSopenharmony_ci */ 1133d0407baSopenharmony_ci void (*unpin)(struct dma_buf_attachment *attach); 1143d0407baSopenharmony_ci 1153d0407baSopenharmony_ci /** 1163d0407baSopenharmony_ci * @map_dma_buf 1173d0407baSopenharmony_ci * 1183d0407baSopenharmony_ci * This is called by dma_buf_map_attachment() and is used to map a 1193d0407baSopenharmony_ci * shared &dma_buf into device address space, and it is mandatory. It 1203d0407baSopenharmony_ci * can only be called if @attach has been called successfully. 1213d0407baSopenharmony_ci * 1223d0407baSopenharmony_ci * This call may sleep, e.g. when the backing storage first needs to be 1233d0407baSopenharmony_ci * allocated, or moved to a location suitable for all currently attached 1243d0407baSopenharmony_ci * devices. 1253d0407baSopenharmony_ci * 1263d0407baSopenharmony_ci * Note that any specific buffer attributes required for this function 1273d0407baSopenharmony_ci * should get added to device_dma_parameters accessible via 1283d0407baSopenharmony_ci * &device.dma_params from the &dma_buf_attachment. The @attach callback 1293d0407baSopenharmony_ci * should also check these constraints. 1303d0407baSopenharmony_ci * 1313d0407baSopenharmony_ci * If this is being called for the first time, the exporter can now 1323d0407baSopenharmony_ci * choose to scan through the list of attachments for this buffer, 1333d0407baSopenharmony_ci * collate the requirements of the attached devices, and choose an 1343d0407baSopenharmony_ci * appropriate backing storage for the buffer. 1353d0407baSopenharmony_ci * 1363d0407baSopenharmony_ci * Based on enum dma_data_direction, it might be possible to have 1373d0407baSopenharmony_ci * multiple users accessing at the same time (for reading, maybe), or 1383d0407baSopenharmony_ci * any other kind of sharing that the exporter might wish to make 1393d0407baSopenharmony_ci * available to buffer-users. 1403d0407baSopenharmony_ci * 1413d0407baSopenharmony_ci * This is always called with the dmabuf->resv object locked when 1423d0407baSopenharmony_ci * the dynamic_mapping flag is true. 1433d0407baSopenharmony_ci * 1443d0407baSopenharmony_ci * Returns 1453d0407baSopenharmony_ci * 1463d0407baSopenharmony_ci * A &sg_table scatter list of or the backing storage of the DMA buffer, 1473d0407baSopenharmony_ci * already mapped into the device address space of the &device attached 1483d0407baSopenharmony_ci * with the provided &dma_buf_attachment. 1493d0407baSopenharmony_ci * 1503d0407baSopenharmony_ci * On failure, returns a negative error value wrapped into a pointer. 1513d0407baSopenharmony_ci * May also return -EINTR when a signal was received while being 1523d0407baSopenharmony_ci * blocked. 1533d0407baSopenharmony_ci */ 1543d0407baSopenharmony_ci struct sg_table *(*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); 1553d0407baSopenharmony_ci /** 1563d0407baSopenharmony_ci * @unmap_dma_buf 1573d0407baSopenharmony_ci * 1583d0407baSopenharmony_ci * This is called by dma_buf_unmap_attachment() and should unmap and 1593d0407baSopenharmony_ci * release the &sg_table allocated in @map_dma_buf, and it is mandatory. 1603d0407baSopenharmony_ci * For static dma_buf handling this might also unpins the backing 1613d0407baSopenharmony_ci * storage if this is the last mapping of the DMA buffer. 1623d0407baSopenharmony_ci */ 1633d0407baSopenharmony_ci void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); 1643d0407baSopenharmony_ci 1653d0407baSopenharmony_ci /* Add try_map_dma_buf version, to return immed with -EBUSY 1663d0407baSopenharmony_ci * if the call would block. 1673d0407baSopenharmony_ci */ 1683d0407baSopenharmony_ci 1693d0407baSopenharmony_ci /** 1703d0407baSopenharmony_ci * @release 1713d0407baSopenharmony_ci * 1723d0407baSopenharmony_ci * Called after the last dma_buf_put to release the &dma_buf, and 1733d0407baSopenharmony_ci * mandatory. 1743d0407baSopenharmony_ci */ 1753d0407baSopenharmony_ci void (*release)(struct dma_buf *); 1763d0407baSopenharmony_ci 1773d0407baSopenharmony_ci /** 1783d0407baSopenharmony_ci * @begin_cpu_access 1793d0407baSopenharmony_ci * 1803d0407baSopenharmony_ci * This is called from dma_buf_begin_cpu_access() and allows the 1813d0407baSopenharmony_ci * exporter to ensure that the memory is actually available for cpu 1823d0407baSopenharmony_ci * access - the exporter might need to allocate or swap-in and pin the 1833d0407baSopenharmony_ci * backing storage. The exporter also needs to ensure that cpu access is 1843d0407baSopenharmony_ci * coherent for the access direction. The direction can be used by the 1853d0407baSopenharmony_ci * exporter to optimize the cache flushing, i.e. access with a different 1863d0407baSopenharmony_ci * direction (read instead of write) might return stale or even bogus 1873d0407baSopenharmony_ci * data (e.g. when the exporter needs to copy the data to temporary 1883d0407baSopenharmony_ci * storage). 1893d0407baSopenharmony_ci * 1903d0407baSopenharmony_ci * This callback is optional. 1913d0407baSopenharmony_ci * 1923d0407baSopenharmony_ci * This is both called through the DMA_BUF_IOCTL_SYNC command 1933d0407baSopenharmony_ci * from userspace (where storage shouldn't be pinned to avoid handing 1943d0407baSopenharmony_ci * de-factor mlock rights to userspace) and for the kernel-internal 1953d0407baSopenharmony_ci * users of the various kmap interfaces, where the backing storage must 1963d0407baSopenharmony_ci * be pinned to guarantee that the atomic kmap calls can succeed. Since 1973d0407baSopenharmony_ci * there's no in-kernel users of the kmap interfaces yet this isn't a 1983d0407baSopenharmony_ci * real problem. 1993d0407baSopenharmony_ci * 2003d0407baSopenharmony_ci * Returns 2013d0407baSopenharmony_ci * 2023d0407baSopenharmony_ci * 0 on success or a negative error code on failure. This can for 2033d0407baSopenharmony_ci * example fail when the backing storage can't be allocated. Can also 2043d0407baSopenharmony_ci * return -ERESTARTSYS or -EINTR when the call has been interrupted and 2053d0407baSopenharmony_ci * needs to be restarted. 2063d0407baSopenharmony_ci */ 2073d0407baSopenharmony_ci int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); 2083d0407baSopenharmony_ci 2093d0407baSopenharmony_ci /** 2103d0407baSopenharmony_ci * @begin_cpu_access_partial 2113d0407baSopenharmony_ci * 2123d0407baSopenharmony_ci * This is called from dma_buf_begin_cpu_access_partial() and allows the 2133d0407baSopenharmony_ci * exporter to ensure that the memory specified in the range is 2143d0407baSopenharmony_ci * available for cpu access - the exporter might need to allocate or 2153d0407baSopenharmony_ci * swap-in and pin the backing storage. 2163d0407baSopenharmony_ci * The exporter also needs to ensure that cpu access is 2173d0407baSopenharmony_ci * coherent for the access direction. The direction can be used by the 2183d0407baSopenharmony_ci * exporter to optimize the cache flushing, i.e. access with a different 2193d0407baSopenharmony_ci * direction (read instead of write) might return stale or even bogus 2203d0407baSopenharmony_ci * data (e.g. when the exporter needs to copy the data to temporary 2213d0407baSopenharmony_ci * storage). 2223d0407baSopenharmony_ci * 2233d0407baSopenharmony_ci * This callback is optional. 2243d0407baSopenharmony_ci * 2253d0407baSopenharmony_ci * This is both called through the DMA_BUF_IOCTL_SYNC command 2263d0407baSopenharmony_ci * from userspace (where storage shouldn't be pinned to avoid handing 2273d0407baSopenharmony_ci * de-factor mlock rights to userspace) and for the kernel-internal 2283d0407baSopenharmony_ci * users of the various kmap interfaces, where the backing storage must 2293d0407baSopenharmony_ci * be pinned to guarantee that the atomic kmap calls can succeed. Since 2303d0407baSopenharmony_ci * there's no in-kernel users of the kmap interfaces yet this isn't a 2313d0407baSopenharmony_ci * real problem. 2323d0407baSopenharmony_ci * 2333d0407baSopenharmony_ci * Returns 2343d0407baSopenharmony_ci * 2353d0407baSopenharmony_ci * 0 on success or a negative error code on failure. This can for 2363d0407baSopenharmony_ci * example fail when the backing storage can't be allocated. Can also 2373d0407baSopenharmony_ci * return -ERESTARTSYS or -EINTR when the call has been interrupted and 2383d0407baSopenharmony_ci * needs to be restarted. 2393d0407baSopenharmony_ci */ 2403d0407baSopenharmony_ci int (*begin_cpu_access_partial)(struct dma_buf *dmabuf, enum dma_data_direction, unsigned int offset, 2413d0407baSopenharmony_ci unsigned int len); 2423d0407baSopenharmony_ci 2433d0407baSopenharmony_ci /** 2443d0407baSopenharmony_ci * @end_cpu_access 2453d0407baSopenharmony_ci * 2463d0407baSopenharmony_ci * This is called from dma_buf_end_cpu_access() when the importer is 2473d0407baSopenharmony_ci * done accessing the CPU. The exporter can use this to flush caches and 2483d0407baSopenharmony_ci * unpin any resources pinned in @begin_cpu_access. 2493d0407baSopenharmony_ci * The result of any dma_buf kmap calls after end_cpu_access is 2503d0407baSopenharmony_ci * undefined. 2513d0407baSopenharmony_ci * 2523d0407baSopenharmony_ci * This callback is optional. 2533d0407baSopenharmony_ci * 2543d0407baSopenharmony_ci * Returns 2553d0407baSopenharmony_ci * 2563d0407baSopenharmony_ci * 0 on success or a negative error code on failure. Can return 2573d0407baSopenharmony_ci * -ERESTARTSYS or -EINTR when the call has been interrupted and needs 2583d0407baSopenharmony_ci * to be restarted. 2593d0407baSopenharmony_ci */ 2603d0407baSopenharmony_ci int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); 2613d0407baSopenharmony_ci 2623d0407baSopenharmony_ci /** 2633d0407baSopenharmony_ci * @end_cpu_access_partial 2643d0407baSopenharmony_ci * 2653d0407baSopenharmony_ci * This is called from dma_buf_end_cpu_access_partial() when the 2663d0407baSopenharmony_ci * importer is done accessing the CPU. The exporter can use to limit 2673d0407baSopenharmony_ci * cache flushing to only the range specefied and to unpin any 2683d0407baSopenharmony_ci * resources pinned in @begin_cpu_access_umapped. 2693d0407baSopenharmony_ci * The result of any dma_buf kmap calls after end_cpu_access_partial is 2703d0407baSopenharmony_ci * undefined. 2713d0407baSopenharmony_ci * 2723d0407baSopenharmony_ci * This callback is optional. 2733d0407baSopenharmony_ci * 2743d0407baSopenharmony_ci * Returns 2753d0407baSopenharmony_ci * 2763d0407baSopenharmony_ci * 0 on success or a negative error code on failure. Can return 2773d0407baSopenharmony_ci * -ERESTARTSYS or -EINTR when the call has been interrupted and needs 2783d0407baSopenharmony_ci * to be restarted. 2793d0407baSopenharmony_ci */ 2803d0407baSopenharmony_ci int (*end_cpu_access_partial)(struct dma_buf *dmabuf, enum dma_data_direction, unsigned int offset, 2813d0407baSopenharmony_ci unsigned int len); 2823d0407baSopenharmony_ci 2833d0407baSopenharmony_ci /** 2843d0407baSopenharmony_ci * @mmap 2853d0407baSopenharmony_ci * 2863d0407baSopenharmony_ci * This callback is used by the dma_buf_mmap() function 2873d0407baSopenharmony_ci * 2883d0407baSopenharmony_ci * Note that the mapping needs to be incoherent, userspace is expected 2893d0407baSopenharmony_ci * to braket CPU access using the DMA_BUF_IOCTL_SYNC interface. 2903d0407baSopenharmony_ci * 2913d0407baSopenharmony_ci * Because dma-buf buffers have invariant size over their lifetime, the 2923d0407baSopenharmony_ci * dma-buf core checks whether a vma is too large and rejects such 2933d0407baSopenharmony_ci * mappings. The exporter hence does not need to duplicate this check. 2943d0407baSopenharmony_ci * Drivers do not need to check this themselves. 2953d0407baSopenharmony_ci * 2963d0407baSopenharmony_ci * If an exporter needs to manually flush caches and hence needs to fake 2973d0407baSopenharmony_ci * coherency for mmap support, it needs to be able to zap all the ptes 2983d0407baSopenharmony_ci * pointing at the backing storage. Now linux mm needs a struct 2993d0407baSopenharmony_ci * address_space associated with the struct file stored in vma->vm_file 3003d0407baSopenharmony_ci * to do that with the function unmap_mapping_range. But the dma_buf 3013d0407baSopenharmony_ci * framework only backs every dma_buf fd with the anon_file struct file, 3023d0407baSopenharmony_ci * i.e. all dma_bufs share the same file. 3033d0407baSopenharmony_ci * 3043d0407baSopenharmony_ci * Hence exporters need to setup their own file (and address_space) 3053d0407baSopenharmony_ci * association by setting vma->vm_file and adjusting vma->vm_pgoff in 3063d0407baSopenharmony_ci * the dma_buf mmap callback. In the specific case of a gem driver the 3073d0407baSopenharmony_ci * exporter could use the shmem file already provided by gem (and set 3083d0407baSopenharmony_ci * vm_pgoff = 0). Exporters can then zap ptes by unmapping the 3093d0407baSopenharmony_ci * corresponding range of the struct address_space associated with their 3103d0407baSopenharmony_ci * own file. 3113d0407baSopenharmony_ci * 3123d0407baSopenharmony_ci * This callback is optional. 3133d0407baSopenharmony_ci * 3143d0407baSopenharmony_ci * Returns 3153d0407baSopenharmony_ci * 3163d0407baSopenharmony_ci * 0 on success or a negative error code on failure. 3173d0407baSopenharmony_ci */ 3183d0407baSopenharmony_ci int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); 3193d0407baSopenharmony_ci 3203d0407baSopenharmony_ci void *(*vmap)(struct dma_buf *); 3213d0407baSopenharmony_ci void (*vunmap)(struct dma_buf *, void *vaddr); 3223d0407baSopenharmony_ci 3233d0407baSopenharmony_ci /** 3243d0407baSopenharmony_ci * @get_uuid 3253d0407baSopenharmony_ci * 3263d0407baSopenharmony_ci * This is called by dma_buf_get_uuid to get the UUID which identifies 3273d0407baSopenharmony_ci * the buffer to virtio devices. 3283d0407baSopenharmony_ci * 3293d0407baSopenharmony_ci * This callback is optional. 3303d0407baSopenharmony_ci * 3313d0407baSopenharmony_ci * Returns 3323d0407baSopenharmony_ci * 3333d0407baSopenharmony_ci * 0 on success or a negative error code on failure. On success uuid 3343d0407baSopenharmony_ci * will be populated with the buffer's UUID. 3353d0407baSopenharmony_ci */ 3363d0407baSopenharmony_ci int (*get_uuid)(struct dma_buf *dmabuf, uuid_t *uuid); 3373d0407baSopenharmony_ci 3383d0407baSopenharmony_ci /** 3393d0407baSopenharmony_ci * @get_flags 3403d0407baSopenharmony_ci * 3413d0407baSopenharmony_ci * This is called by dma_buf_get_flags and is used to get the buffer's 3423d0407baSopenharmony_ci * flags. 3433d0407baSopenharmony_ci * This callback is optional. 3443d0407baSopenharmony_ci * 3453d0407baSopenharmony_ci * Returns 3463d0407baSopenharmony_ci * 3473d0407baSopenharmony_ci * 0 on success or a negative error code on failure. On success flags 3483d0407baSopenharmony_ci * will be populated with the buffer's flags. 3493d0407baSopenharmony_ci */ 3503d0407baSopenharmony_ci int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags); 3513d0407baSopenharmony_ci}; 3523d0407baSopenharmony_ci 3533d0407baSopenharmony_ci/** 3543d0407baSopenharmony_ci * struct dma_buf - shared buffer object 3553d0407baSopenharmony_ci * @size: size of the buffer 3563d0407baSopenharmony_ci * @file: file pointer used for sharing buffers across, and for refcounting. 3573d0407baSopenharmony_ci * @attachments: list of dma_buf_attachment that denotes all devices attached, 3583d0407baSopenharmony_ci * protected by dma_resv lock. 3593d0407baSopenharmony_ci * @ops: dma_buf_ops associated with this buffer object. 3603d0407baSopenharmony_ci * @lock: used internally to serialize list manipulation, attach/detach and 3613d0407baSopenharmony_ci * vmap/unmap 3623d0407baSopenharmony_ci * @vmapping_counter: used internally to refcnt the vmaps 3633d0407baSopenharmony_ci * @vmap_ptr: the current vmap ptr if vmapping_counter > 0 3643d0407baSopenharmony_ci * @exp_name: name of the exporter; useful for debugging. 3653d0407baSopenharmony_ci * @name: userspace-provided name; useful for accounting and debugging, 3663d0407baSopenharmony_ci * protected by @resv. 3673d0407baSopenharmony_ci * @name_lock: spinlock to protect name access 3683d0407baSopenharmony_ci * @owner: pointer to exporter module; used for refcounting when exporter is a 3693d0407baSopenharmony_ci * kernel module. 3703d0407baSopenharmony_ci * @list_node: node for dma_buf accounting and debugging. 3713d0407baSopenharmony_ci * @priv: exporter specific private data for this buffer object. 3723d0407baSopenharmony_ci * @resv: reservation object linked to this dma-buf 3733d0407baSopenharmony_ci * @exp_pid: pid of exporter task which created this obj 3743d0407baSopenharmony_ci * @exp_task_comm: process name of exporter task which created this obj 3753d0407baSopenharmony_ci * @poll: for userspace poll support 3763d0407baSopenharmony_ci * @cb_excl: for userspace poll support 3773d0407baSopenharmony_ci * @cb_shared: for userspace poll support 3783d0407baSopenharmony_ci * @sysfs_entry: for exposing information about this buffer in sysfs. 3793d0407baSopenharmony_ci * @mmap_count: number of times buffer has been mmapped. 3803d0407baSopenharmony_ci * @exp_vm_ops: the vm ops provided by the buffer exporter. 3813d0407baSopenharmony_ci * @vm_ops: the overridden vm_ops used to track mmap_count of the buffer. 3823d0407baSopenharmony_ci * 3833d0407baSopenharmony_ci * This represents a shared buffer, created by calling dma_buf_export(). The 3843d0407baSopenharmony_ci * userspace representation is a normal file descriptor, which can be created by 3853d0407baSopenharmony_ci * calling dma_buf_fd(). 3863d0407baSopenharmony_ci * 3873d0407baSopenharmony_ci * Shared dma buffers are reference counted using dma_buf_put() and 3883d0407baSopenharmony_ci * get_dma_buf(). 3893d0407baSopenharmony_ci * 3903d0407baSopenharmony_ci * Device DMA access is handled by the separate &struct dma_buf_attachment. 3913d0407baSopenharmony_ci */ 3923d0407baSopenharmony_cistruct dma_buf { 3933d0407baSopenharmony_ci size_t size; 3943d0407baSopenharmony_ci struct file *file; 3953d0407baSopenharmony_ci struct list_head attachments; 3963d0407baSopenharmony_ci const struct dma_buf_ops *ops; 3973d0407baSopenharmony_ci struct mutex lock; 3983d0407baSopenharmony_ci unsigned vmapping_counter; 3993d0407baSopenharmony_ci void *vmap_ptr; 4003d0407baSopenharmony_ci const char *exp_name; 4013d0407baSopenharmony_ci const char *name; 4023d0407baSopenharmony_ci spinlock_t name_lock; 4033d0407baSopenharmony_ci struct module *owner; 4043d0407baSopenharmony_ci struct list_head list_node; 4053d0407baSopenharmony_ci void *priv; 4063d0407baSopenharmony_ci struct dma_resv *resv; 4073d0407baSopenharmony_ci#ifdef CONFIG_DMABUF_PROCESS_INFO 4083d0407baSopenharmony_ci pid_t exp_pid; 4093d0407baSopenharmony_ci char exp_task_comm[TASK_COMM_LEN]; 4103d0407baSopenharmony_ci#endif 4113d0407baSopenharmony_ci 4123d0407baSopenharmony_ci /* poll support */ 4133d0407baSopenharmony_ci wait_queue_head_t poll; 4143d0407baSopenharmony_ci 4153d0407baSopenharmony_ci struct dma_buf_poll_cb_t { 4163d0407baSopenharmony_ci struct dma_fence_cb cb; 4173d0407baSopenharmony_ci wait_queue_head_t *poll; 4183d0407baSopenharmony_ci 4193d0407baSopenharmony_ci __poll_t active; 4203d0407baSopenharmony_ci } cb_excl, cb_shared; 4213d0407baSopenharmony_ci#ifdef CONFIG_DMABUF_SYSFS_STATS 4223d0407baSopenharmony_ci /* for sysfs stats */ 4233d0407baSopenharmony_ci struct dma_buf_sysfs_entry { 4243d0407baSopenharmony_ci struct kobject kobj; 4253d0407baSopenharmony_ci struct dma_buf *dmabuf; 4263d0407baSopenharmony_ci } *sysfs_entry; 4273d0407baSopenharmony_ci int mmap_count; 4283d0407baSopenharmony_ci const struct vm_operations_struct *exp_vm_ops; 4293d0407baSopenharmony_ci struct vm_operations_struct vm_ops; 4303d0407baSopenharmony_ci#endif 4313d0407baSopenharmony_ci}; 4323d0407baSopenharmony_ci 4333d0407baSopenharmony_ci/** 4343d0407baSopenharmony_ci * struct dma_buf_attach_ops - importer operations for an attachment 4353d0407baSopenharmony_ci * 4363d0407baSopenharmony_ci * Attachment operations implemented by the importer. 4373d0407baSopenharmony_ci */ 4383d0407baSopenharmony_cistruct dma_buf_attach_ops { 4393d0407baSopenharmony_ci /** 4403d0407baSopenharmony_ci * @allow_peer2peer: 4413d0407baSopenharmony_ci * 4423d0407baSopenharmony_ci * If this is set to true the importer must be able to handle peer 4433d0407baSopenharmony_ci * resources without struct pages. 4443d0407baSopenharmony_ci */ 4453d0407baSopenharmony_ci bool allow_peer2peer; 4463d0407baSopenharmony_ci 4473d0407baSopenharmony_ci /** 4483d0407baSopenharmony_ci * @move_notify: [optional] notification that the DMA-buf is moving 4493d0407baSopenharmony_ci * 4503d0407baSopenharmony_ci * If this callback is provided the framework can avoid pinning the 4513d0407baSopenharmony_ci * backing store while mappings exists. 4523d0407baSopenharmony_ci * 4533d0407baSopenharmony_ci * This callback is called with the lock of the reservation object 4543d0407baSopenharmony_ci * associated with the dma_buf held and the mapping function must be 4553d0407baSopenharmony_ci * called with this lock held as well. This makes sure that no mapping 4563d0407baSopenharmony_ci * is created concurrently with an ongoing move operation. 4573d0407baSopenharmony_ci * 4583d0407baSopenharmony_ci * Mappings stay valid and are not directly affected by this callback. 4593d0407baSopenharmony_ci * But the DMA-buf can now be in a different physical location, so all 4603d0407baSopenharmony_ci * mappings should be destroyed and re-created as soon as possible. 4613d0407baSopenharmony_ci * 4623d0407baSopenharmony_ci * New mappings can be created after this callback returns, and will 4633d0407baSopenharmony_ci * point to the new location of the DMA-buf. 4643d0407baSopenharmony_ci */ 4653d0407baSopenharmony_ci void (*move_notify)(struct dma_buf_attachment *attach); 4663d0407baSopenharmony_ci}; 4673d0407baSopenharmony_ci 4683d0407baSopenharmony_ci/** 4693d0407baSopenharmony_ci * struct dma_buf_attachment - holds device-buffer attachment data 4703d0407baSopenharmony_ci * @dmabuf: buffer for this attachment. 4713d0407baSopenharmony_ci * @dev: device attached to the buffer. 4723d0407baSopenharmony_ci * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf. 4733d0407baSopenharmony_ci * @sgt: cached mapping. 4743d0407baSopenharmony_ci * @dir: direction of cached mapping. 4753d0407baSopenharmony_ci * @peer2peer: true if the importer can handle peer resources without pages. 4763d0407baSopenharmony_ci * @priv: exporter specific attachment data. 4773d0407baSopenharmony_ci * @importer_ops: importer operations for this attachment, if provided 4783d0407baSopenharmony_ci * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held. 4793d0407baSopenharmony_ci * @importer_priv: importer specific attachment data. 4803d0407baSopenharmony_ci * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer 4813d0407baSopenharmony_ci * through dma_buf_map_attachment. 4823d0407baSopenharmony_ci * @sysfs_entry: For exposing information about this attachment in sysfs. 4833d0407baSopenharmony_ci * 4843d0407baSopenharmony_ci * This structure holds the attachment information between the dma_buf buffer 4853d0407baSopenharmony_ci * and its user device(s). The list contains one attachment struct per device 4863d0407baSopenharmony_ci * attached to the buffer. 4873d0407baSopenharmony_ci * 4883d0407baSopenharmony_ci * An attachment is created by calling dma_buf_attach(), and released again by 4893d0407baSopenharmony_ci * calling dma_buf_detach(). The DMA mapping itself needed to initiate a 4903d0407baSopenharmony_ci * transfer is created by dma_buf_map_attachment() and freed again by calling 4913d0407baSopenharmony_ci * dma_buf_unmap_attachment(). 4923d0407baSopenharmony_ci */ 4933d0407baSopenharmony_cistruct dma_buf_attachment { 4943d0407baSopenharmony_ci struct dma_buf *dmabuf; 4953d0407baSopenharmony_ci struct device *dev; 4963d0407baSopenharmony_ci struct list_head node; 4973d0407baSopenharmony_ci struct sg_table *sgt; 4983d0407baSopenharmony_ci enum dma_data_direction dir; 4993d0407baSopenharmony_ci bool peer2peer; 5003d0407baSopenharmony_ci const struct dma_buf_attach_ops *importer_ops; 5013d0407baSopenharmony_ci void *importer_priv; 5023d0407baSopenharmony_ci void *priv; 5033d0407baSopenharmony_ci unsigned long dma_map_attrs; 5043d0407baSopenharmony_ci#ifdef CONFIG_DMABUF_SYSFS_STATS 5053d0407baSopenharmony_ci /* for sysfs stats */ 5063d0407baSopenharmony_ci struct dma_buf_attach_sysfs_entry { 5073d0407baSopenharmony_ci struct kobject kobj; 5083d0407baSopenharmony_ci unsigned int map_counter; 5093d0407baSopenharmony_ci } *sysfs_entry; 5103d0407baSopenharmony_ci#endif 5113d0407baSopenharmony_ci}; 5123d0407baSopenharmony_ci 5133d0407baSopenharmony_ci/** 5143d0407baSopenharmony_ci * struct dma_buf_export_info - holds information needed to export a dma_buf 5153d0407baSopenharmony_ci * @exp_name: name of the exporter - useful for debugging. 5163d0407baSopenharmony_ci * @owner: pointer to exporter module - used for refcounting kernel module 5173d0407baSopenharmony_ci * @ops: Attach allocator-defined dma buf ops to the new buffer 5183d0407baSopenharmony_ci * @size: Size of the buffer 5193d0407baSopenharmony_ci * @flags: mode flags for the file 5203d0407baSopenharmony_ci * @resv: reservation-object, NULL to allocate default one 5213d0407baSopenharmony_ci * @priv: Attach private data of allocator to this buffer 5223d0407baSopenharmony_ci * 5233d0407baSopenharmony_ci * This structure holds the information required to export the buffer. Used 5243d0407baSopenharmony_ci * with dma_buf_export() only. 5253d0407baSopenharmony_ci */ 5263d0407baSopenharmony_cistruct dma_buf_export_info { 5273d0407baSopenharmony_ci const char *exp_name; 5283d0407baSopenharmony_ci struct module *owner; 5293d0407baSopenharmony_ci const struct dma_buf_ops *ops; 5303d0407baSopenharmony_ci size_t size; 5313d0407baSopenharmony_ci int flags; 5323d0407baSopenharmony_ci struct dma_resv *resv; 5333d0407baSopenharmony_ci void *priv; 5343d0407baSopenharmony_ci}; 5353d0407baSopenharmony_ci 5363d0407baSopenharmony_ci/** 5373d0407baSopenharmony_ci * DEFINE_DMA_BUF_EXPORT_INFO - helper macro for exporters 5383d0407baSopenharmony_ci * @name: export-info name 5393d0407baSopenharmony_ci * 5403d0407baSopenharmony_ci * DEFINE_DMA_BUF_EXPORT_INFO macro defines the &struct dma_buf_export_info, 5413d0407baSopenharmony_ci * zeroes it out and pre-populates exp_name in it. 5423d0407baSopenharmony_ci */ 5433d0407baSopenharmony_ci#define DEFINE_DMA_BUF_EXPORT_INFO(name) \ 5443d0407baSopenharmony_ci struct dma_buf_export_info name = {.exp_name = KBUILD_MODNAME, .owner = THIS_MODULE} 5453d0407baSopenharmony_ci 5463d0407baSopenharmony_ci/** 5473d0407baSopenharmony_ci * get_dma_buf - convenience wrapper for get_file. 5483d0407baSopenharmony_ci * @dmabuf: [in] pointer to dma_buf 5493d0407baSopenharmony_ci * 5503d0407baSopenharmony_ci * Increments the reference count on the dma-buf, needed in case of drivers 5513d0407baSopenharmony_ci * that either need to create additional references to the dmabuf on the 5523d0407baSopenharmony_ci * kernel side. For example, an exporter that needs to keep a dmabuf ptr 5533d0407baSopenharmony_ci * so that subsequent exports don't create a new dmabuf. 5543d0407baSopenharmony_ci */ 5553d0407baSopenharmony_cistatic inline void get_dma_buf(struct dma_buf *dmabuf) 5563d0407baSopenharmony_ci{ 5573d0407baSopenharmony_ci get_file(dmabuf->file); 5583d0407baSopenharmony_ci} 5593d0407baSopenharmony_ci 5603d0407baSopenharmony_ci/** 5613d0407baSopenharmony_ci * dma_buf_is_dynamic - check if a DMA-buf uses dynamic mappings. 5623d0407baSopenharmony_ci * @dmabuf: the DMA-buf to check 5633d0407baSopenharmony_ci * 5643d0407baSopenharmony_ci * Returns true if a DMA-buf exporter wants to be called with the dma_resv 5653d0407baSopenharmony_ci * locked for the map/unmap callbacks, false if it doesn't wants to be called 5663d0407baSopenharmony_ci * with the lock held. 5673d0407baSopenharmony_ci */ 5683d0407baSopenharmony_cistatic inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf) 5693d0407baSopenharmony_ci{ 5703d0407baSopenharmony_ci return !!dmabuf->ops->pin; 5713d0407baSopenharmony_ci} 5723d0407baSopenharmony_ci 5733d0407baSopenharmony_ci/** 5743d0407baSopenharmony_ci * dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic 5753d0407baSopenharmony_ci * mappinsg 5763d0407baSopenharmony_ci * @attach: the DMA-buf attachment to check 5773d0407baSopenharmony_ci * 5783d0407baSopenharmony_ci * Returns true if a DMA-buf importer wants to call the map/unmap functions with 5793d0407baSopenharmony_ci * the dma_resv lock held. 5803d0407baSopenharmony_ci */ 5813d0407baSopenharmony_cistatic inline bool dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach) 5823d0407baSopenharmony_ci{ 5833d0407baSopenharmony_ci return !!attach->importer_ops; 5843d0407baSopenharmony_ci} 5853d0407baSopenharmony_ci 5863d0407baSopenharmony_ciint get_each_dmabuf(int (*callback)(const struct dma_buf *dmabuf, void *private), void *private); 5873d0407baSopenharmony_ciint is_dma_buf_file(struct file *file); 5883d0407baSopenharmony_cistruct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); 5893d0407baSopenharmony_cistruct dma_buf_attachment *dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, 5903d0407baSopenharmony_ci const struct dma_buf_attach_ops *importer_ops, void *importer_priv); 5913d0407baSopenharmony_civoid dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach); 5923d0407baSopenharmony_ciint dma_buf_pin(struct dma_buf_attachment *attach); 5933d0407baSopenharmony_civoid dma_buf_unpin(struct dma_buf_attachment *attach); 5943d0407baSopenharmony_ci 5953d0407baSopenharmony_cistruct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info); 5963d0407baSopenharmony_ci 5973d0407baSopenharmony_ciint dma_buf_fd(struct dma_buf *dmabuf, int flags); 5983d0407baSopenharmony_cistruct dma_buf *dma_buf_get(int fd); 5993d0407baSopenharmony_civoid dma_buf_put(struct dma_buf *dmabuf); 6003d0407baSopenharmony_ci 6013d0407baSopenharmony_cistruct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); 6023d0407baSopenharmony_civoid dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); 6033d0407baSopenharmony_civoid dma_buf_move_notify(struct dma_buf *dma_buf); 6043d0407baSopenharmony_ciint dma_buf_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction dir); 6053d0407baSopenharmony_ciint dma_buf_begin_cpu_access_partial(struct dma_buf *dma_buf, enum dma_data_direction dir, unsigned int offset, 6063d0407baSopenharmony_ci unsigned int len); 6073d0407baSopenharmony_ciint dma_buf_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction dir); 6083d0407baSopenharmony_ciint dma_buf_end_cpu_access_partial(struct dma_buf *dma_buf, enum dma_data_direction dir, unsigned int offset, 6093d0407baSopenharmony_ci unsigned int len); 6103d0407baSopenharmony_ci 6113d0407baSopenharmony_ciint dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); 6123d0407baSopenharmony_civoid *dma_buf_vmap(struct dma_buf *); 6133d0407baSopenharmony_civoid dma_buf_vunmap(struct dma_buf *, void *vaddr); 6143d0407baSopenharmony_ciint dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags); 6153d0407baSopenharmony_ciint dma_buf_get_uuid(struct dma_buf *dmabuf, uuid_t *uuid); 6163d0407baSopenharmony_ci 6173d0407baSopenharmony_ci#ifdef CONFIG_DMABUF_PROCESS_INFO 6183d0407baSopenharmony_ci/** 6193d0407baSopenharmony_ci * get_dma_buf_from_file - Get struct dma_buf* from struct file* 6203d0407baSopenharmony_ci * @f: [in] pointer to struct file, which is associated with a 6213d0407baSopenharmony_ci * dma_buf object. 6223d0407baSopenharmony_ci * 6233d0407baSopenharmony_ci * If @f IS_ERR_OR_NULL, return NULL. 6243d0407baSopenharmony_ci * If @f is not a file associated with dma_buf, return NULL. 6253d0407baSopenharmony_ci */ 6263d0407baSopenharmony_cistruct dma_buf *get_dma_buf_from_file(struct file *f); 6273d0407baSopenharmony_ci#endif /* CONFIG_DMABUF_PROCESS_INFO */ 6283d0407baSopenharmony_ci#endif /* __DMA_BUF_H__ */ 629