Changeset 3e6ff9a in mainline for uspace/lib/usb/src/dma_buffer.c
- Timestamp:
- 2018-02-01T14:28:41Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e67c50a
- Parents:
- 77ded647
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/dma_buffer.c
r77ded647 r3e6ff9a 40 40 41 41 const dma_policy_t dma_policy_default = { 42 .use64 = false, 43 .alignment = PAGE_SIZE, 42 .flags = DMA_POLICY_F_4GiB | DMA_POLICY_F_CONTIGUOUS, 44 43 }; 45 44 … … 47 46 * The routine of allocating a DMA buffer. Inlined to force optimization for the 48 47 * default policy. 48 * 49 * FIXME: We ignore the non-presence of contiguous flag, for now. 49 50 */ 50 51 static inline int dma_buffer_alloc_internal(dma_buffer_t *db, … … 53 54 assert(db); 54 55 55 if (policy->alignment > PAGE_SIZE)56 return EINVAL;56 const size_t real_size = ALIGN_UP(size, PAGE_SIZE); 57 const bool need_4gib = !!(policy->flags & DMA_POLICY_F_4GiB); 57 58 58 const size_t aligned_size = ALIGN_UP(size, policy->alignment); 59 const size_t real_size = ALIGN_UP(aligned_size, PAGE_SIZE); 60 const uintptr_t flags = policy->use64 ? 0 : DMAMEM_4GiB; 59 const uintptr_t flags = need_4gib ? DMAMEM_4GiB : 0; 61 60 62 61 uintptr_t phys; … … 127 126 128 127 /** 128 * Check whether a memory area is compatible with a policy. 129 * 130 * Useful to skip copying, if the buffer is already ready to be given to 131 * hardware. 132 */ 133 bool dma_buffer_check_policy(const void *buffer, size_t size, dma_policy_t *policy) 134 { 135 /* Buffer must be always page aligned */ 136 if (((uintptr_t) buffer) % PAGE_SIZE) 137 goto violated; 138 139 const bool check_4gib = !!(policy->flags & DMA_POLICY_F_4GiB); 140 const bool check_contiguous = !!(policy->flags & DMA_POLICY_F_CONTIGUOUS); 141 142 /* 143 * For these conditions, we need to walk through pages and check 144 * physical address of each one 145 */ 146 if (check_contiguous || check_4gib) { 147 const void * virt = buffer; 148 uintptr_t phys; 149 150 /* Get the mapping of the first page */ 151 if (as_get_physical_mapping(virt, &phys)) 152 goto error; 153 154 /* First page can already break 4GiB condition */ 155 if (check_4gib && (phys & DMAMEM_4GiB) != 0) 156 goto violated; 157 158 while (size <= PAGE_SIZE) { 159 /* Move to the next page */ 160 virt += PAGE_SIZE; 161 size -= PAGE_SIZE; 162 163 uintptr_t last_phys = phys; 164 if (as_get_physical_mapping(virt, &phys)) 165 goto error; 166 167 if (check_contiguous && (phys - last_phys) != PAGE_SIZE) 168 goto violated; 169 170 if (check_4gib && (phys & DMAMEM_4GiB) != 0) 171 goto violated; 172 } 173 } 174 175 /* All checks passed */ 176 return true; 177 178 violated: 179 error: 180 return false; 181 } 182 183 /** 129 184 * @} 130 185 */
Note:
See TracChangeset
for help on using the changeset viewer.