qcacmn: Add qdf API to align the allocated memory
Define qdf_aligned_mem_alloc_consistent() and qdf_aligned_malloc() which allocates the memory and checks if allocated base address is aligned with ring_base_align. If not, it frees the memory and re-allocates by adding 7 bytes to alloc_size and returns aligned address to the caller. Change-Id: I412153c20e4e4566450b006356fe78d98f1fd3f0 Acked-by: Shashikala Prabhu <pshashik@codeaurora.org> CRs-Fixed: 2336697
这个提交包含在:
@@ -259,6 +259,58 @@ void qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
|
||||
|
||||
#endif /* MEMORY_DEBUG */
|
||||
|
||||
/**
|
||||
* qdf_aligned_malloc() - allocates aligned QDF memory.
|
||||
* @size: Number of bytes of memory to allocate.
|
||||
* @ring_base_align: Base address alignment.
|
||||
* @vaddr_unaligned: Unaligned virtual address.
|
||||
* @func: Function name of the call site.
|
||||
* @line: Line number of the call site.
|
||||
*
|
||||
* This function will dynamically allocate the specified number of bytes of
|
||||
* memory. Checks if the allocated base address is aligned with base_align.
|
||||
* If not, it frees the allocated memory, adds base_align to alloc size and
|
||||
* re-allocates the memory.
|
||||
*
|
||||
* Return:
|
||||
* Upon successful allocate, returns an aligned base address of the allocated
|
||||
* memory. If this function is unable to allocate the amount of memory
|
||||
* specified (for any reason) it returns NULL.
|
||||
*/
|
||||
#define qdf_aligned_malloc(size, ring_base_align, vaddr_unaligned) \
|
||||
qdf_aligned_malloc_fl(size, ring_base_align, vaddr_unaligned, \
|
||||
__func__, __LINE__)
|
||||
|
||||
void *qdf_aligned_malloc_fl(qdf_size_t size, uint32_t ring_base_align,
|
||||
void **vaddr_unaligned,
|
||||
const char *func, uint32_t line);
|
||||
|
||||
/**
|
||||
* qdf_aligned_mem_alloc_consistent() - allocates consistent qdf memory
|
||||
* @osdev: OS device handle
|
||||
* @dev: Pointer to device handle
|
||||
* @size: Size to be allocated
|
||||
* @vaddr_unaligned: Unaligned virtual address.
|
||||
* @paddr_unaligned: Unaligned physical address.
|
||||
* @paddr_aligned: Aligned physical address.
|
||||
* @ring_base_align: Base address alignment.
|
||||
* @func: Function name of the call site.
|
||||
* @line: Line number of the call site.
|
||||
*
|
||||
* Return: pointer of allocated memory or null if memory alloc fails.
|
||||
*/
|
||||
#define qdf_aligned_mem_alloc_consistent(osdev, dev, size, vaddr_unaligned, \
|
||||
paddr_unaligned, paddr_aligned, ring_base_align) \
|
||||
qdf_aligned_mem_alloc_consistent_fl(osdev, dev, size, vaddr_unaligned, \
|
||||
paddr_unaligned, paddr_aligned, \
|
||||
ring_base_align, __func__, __LINE__)
|
||||
|
||||
void *qdf_aligned_mem_alloc_consistent_fl(
|
||||
qdf_device_t osdev, void *dev, qdf_size_t size,
|
||||
void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned,
|
||||
qdf_dma_addr_t *paddr_aligned, uint32_t ring_base_align,
|
||||
const char *func, uint32_t line);
|
||||
|
||||
void *qdf_mem_alloc_outline(qdf_device_t osdev, qdf_size_t size);
|
||||
|
||||
void qdf_mem_set_io(void *ptr, uint32_t num_bytes, uint32_t value);
|
||||
|
@@ -1200,6 +1200,35 @@ void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line)
|
||||
}
|
||||
qdf_export_symbol(qdf_mem_malloc_atomic_fl);
|
||||
|
||||
void *qdf_aligned_malloc_fl(qdf_size_t size, uint32_t ring_base_align,
|
||||
void **vaddr_unaligned,
|
||||
const char *func, uint32_t line)
|
||||
{
|
||||
void *vaddr_aligned;
|
||||
|
||||
*vaddr_unaligned = qdf_mem_malloc(size);
|
||||
if (!*vaddr_unaligned) {
|
||||
qdf_warn("Failed to alloc %zuB @ %s:%d", size, func, line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((unsigned long)(*vaddr_unaligned) % ring_base_align) {
|
||||
qdf_mem_free(*vaddr_unaligned);
|
||||
*vaddr_unaligned = qdf_mem_malloc(size + ring_base_align - 1);
|
||||
if (!*vaddr_unaligned) {
|
||||
qdf_warn("Failed to alloc %zuB @ %s:%d",
|
||||
size, func, line);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
vaddr_aligned = (*vaddr_unaligned) +
|
||||
((unsigned long)(*vaddr_unaligned) % ring_base_align);
|
||||
|
||||
return vaddr_aligned;
|
||||
}
|
||||
qdf_export_symbol(qdf_aligned_malloc_fl);
|
||||
|
||||
/**
|
||||
* qdf_mem_free() - free QDF memory
|
||||
* @ptr: Pointer to the starting address of the memory to be free'd.
|
||||
@@ -1768,6 +1797,42 @@ qdf_export_symbol(qdf_mem_free_consistent);
|
||||
|
||||
#endif /* MEMORY_DEBUG */
|
||||
|
||||
void *qdf_aligned_mem_alloc_consistent_fl(
|
||||
qdf_device_t osdev, void *dev, qdf_size_t size,
|
||||
void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned,
|
||||
qdf_dma_addr_t *paddr_aligned, uint32_t ring_base_align,
|
||||
const char *func, uint32_t line)
|
||||
{
|
||||
void *vaddr_aligned;
|
||||
|
||||
*vaddr_unaligned = qdf_mem_alloc_consistent(osdev, dev, size,
|
||||
paddr_unaligned);
|
||||
if (!*vaddr_unaligned) {
|
||||
qdf_warn("Failed to alloc %zuB @ %s:%d", size, func, line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((unsigned long)(*vaddr_unaligned) % ring_base_align) {
|
||||
qdf_mem_free_consistent(osdev, dev, size, *vaddr_unaligned,
|
||||
*paddr_unaligned, 0);
|
||||
*vaddr_unaligned = qdf_mem_alloc_consistent(osdev, dev,
|
||||
size + ring_base_align - 1, paddr_unaligned);
|
||||
if (!*vaddr_unaligned) {
|
||||
qdf_warn("Failed to alloc %zuB @ %s:%d",
|
||||
size, func, line);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
vaddr_aligned = *vaddr_unaligned +
|
||||
((unsigned long)(*vaddr_unaligned) % ring_base_align);
|
||||
*paddr_aligned = *paddr_unaligned + ((unsigned long)(vaddr_aligned) -
|
||||
(unsigned long)(*vaddr_unaligned));
|
||||
|
||||
return vaddr_aligned;
|
||||
}
|
||||
qdf_export_symbol(qdf_aligned_mem_alloc_consistent_fl);
|
||||
|
||||
/**
|
||||
* qdf_mem_dma_sync_single_for_device() - assign memory to device
|
||||
* @osdev: OS device handle
|
||||
|
在新工单中引用
屏蔽一个用户