Changeset 1d758fc in mainline for uspace/lib/usb/include/usb/dma_buffer.h
- Timestamp:
- 2018-02-12T10:11:47Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5fe3f954
- Parents:
- 2f762a7
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-02-05 03:28:50)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-02-12 10:11:47)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/dma_buffer.h
r2f762a7 r1d758fc 37 37 * shared through IPC). 38 38 * 39 * Note that although allocated memory is always page-aligned, the buffer itself 40 * may be only a part of it, justifying the existence of page-alignment and 41 * page-crossing flags. 39 * Currently, it is possible to allocate either completely contiguous buffers 40 * (with dma_map_anonymous) or arbitrary memory (with as_area_create). Shall the 41 * kernel be updated, this is a subject of major optimization of memory usage. 42 * The other way to do it without the kernel is building an userspace IO vector 43 * in a similar way how QEMU does it. 42 44 * 43 * Also, currently the buffers that are allocated are always contiguous and 44 * page-aligned, regardless of whether the policy requires it. We blindly 45 * believe this fact in dma_buffer_phys, which will yield wrong results if the 46 * buffer is not contiguous. 45 * The structures themselves are defined in usbhc_iface, because they need to be 46 * passed through IPC. 47 47 */ 48 48 #ifndef LIB_USB_DMA_BUFFER 49 49 #define LIB_USB_DMA_BUFFER 50 50 51 #include <as.h> 52 #include <bitops.h> 53 #include <errno.h> 51 54 #include <stdint.h> 52 55 #include <stdlib.h> 53 56 #include <usbhc_iface.h> 54 #include <errno.h>55 57 56 #define DMA_POLICY_4GiB (1<<0) /**< Must use only 32-bit addresses */ 57 #define DMA_POLICY_PAGE_ALIGNED (1<<1) /**< The first pointer must be page-aligned */ 58 #define DMA_POLICY_CONTIGUOUS (1<<2) /**< Pages must follow each other physically */ 59 #define DMA_POLICY_NOT_CROSSING (1<<3) /**< Buffer must not cross page boundary. (Implies buffer is no larger than page). */ 58 /** 59 * The DMA policy describes properties of the buffer. It is used in two 60 * different contexts. Either it represents requirements, which shall be 61 * satisfied to avoid copying the buffer to a more strict one. Or, it is the 62 * actual property of the buffer, which can be more strict than requested. It 63 * always holds that more bits set means more restrictive policy, and that by 64 * computing a bitwise OR one gets the restriction that holds for both. 65 * 66 * The high bits of a DMA policy represent a physical contiguity. If bit i is 67 * set, it means that chunks of a size 2^(i+1) are contiguous in memory. It 68 * shall never happen that bit i > j is set when j is not. 69 * 70 * The previous applies for i >= PAGE_WIDTH. Lower bits are used as bit flags. 71 */ 72 #define DMA_POLICY_FLAGS_MASK (PAGE_SIZE - 1) 73 #define DMA_POLICY_CHUNK_SIZE_MASK (~DMA_POLICY_FLAGS_MASK) 60 74 61 #define DMA_POLICY_STRICT (-1U) 62 #define DMA_POLICY_DEFAULT DMA_POLICY_STRICT 75 #define DMA_POLICY_4GiB (1<<0) /**< Must use only 32-bit addresses */ 63 76 64 typedef struct dma_buffer { 65 void *virt; 66 uintptr_t phys; 67 } dma_buffer_t; 77 #define DMA_POLICY_STRICT (-1UL) 78 #define DMA_POLICY_DEFAULT DMA_POLICY_STRICT 79 80 extern dma_policy_t dma_policy_create(unsigned, size_t); 81 82 /** 83 * Get mask which defines bits of offset in chunk. 84 */ 85 static inline size_t dma_policy_chunk_mask(const dma_policy_t policy) 86 { 87 return policy | DMA_POLICY_FLAGS_MASK; 88 } 68 89 69 90 extern errno_t dma_buffer_alloc(dma_buffer_t *db, size_t size); 70 91 extern errno_t dma_buffer_alloc_policy(dma_buffer_t *, size_t, dma_policy_t); 71 92 extern void dma_buffer_free(dma_buffer_t *); 72 extern uintptr_t dma_buffer_phys(const dma_buffer_t *, void *);73 93 74 extern bool dma_buffer_check_policy(const void *, size_t, const dma_policy_t); 94 extern uintptr_t dma_buffer_phys(const dma_buffer_t *, const void *); 95 96 static inline uintptr_t dma_buffer_phys_base(const dma_buffer_t *db) 97 { 98 return dma_buffer_phys(db, db->virt); 99 } 75 100 76 101 extern errno_t dma_buffer_lock(dma_buffer_t *, void *, size_t); 77 102 extern void dma_buffer_unlock(dma_buffer_t *, size_t); 78 103 79 static inline int dma_buffer_is_set(dma_buffer_t *db) 104 extern void dma_buffer_acquire(dma_buffer_t *); 105 extern void dma_buffer_release(dma_buffer_t *); 106 107 static inline bool dma_buffer_is_set(const dma_buffer_t *db) 80 108 { 81 109 return !!db->virt;
Note:
See TracChangeset
for help on using the changeset viewer.