diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2011-07-06 03:48:40 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2011-07-06 03:48:40 +0200 |
commit | 5c1e2da736a77fc7172da2c621310a9ceaf1e6ce (patch) | |
tree | 98d18bc0e62de19b9bfac0100183dc630a3999dd | |
parent | e78aba2587be9e79e73ba3275b6c9b2de3c5c71a (diff) | |
download | pcitool-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.gz pcitool-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.bz2 pcitool-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.xz pcitool-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.zip |
Support alignments in kmem allocation
-rw-r--r-- | dma/nwl.c | 2 | ||||
-rw-r--r-- | kmem.c | 28 | ||||
-rw-r--r-- | kmem.h | 3 |
3 files changed, 21 insertions, 12 deletions
@@ -258,7 +258,7 @@ int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_descriptio if (info->pages) return 0; pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA, info->desc.addr), 0); - pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_PAGE, PCILIB_NWL_DMA_PAGES, 0, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA, info->desc.addr), 0); + pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_PAGE, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA, info->desc.addr), 0); if ((ring)&&(pages)) err = dma_nwl_sync_buffers(ctx, info, pages); else err = PCILIB_ERROR_FAILED; @@ -44,6 +44,10 @@ pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type kh.align = alignment; kh.use = use; + if (type != PCILIB_KMEM_TYPE_PAGE) { + kh.size += alignment; + } + for ( i = 0; i < nmemb; i++) { ret = ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_ALLOC, &kh); if (ret) { @@ -56,13 +60,13 @@ pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type kbuf->buf.blocks[i].handle_id = kh.handle_id; kbuf->buf.blocks[i].pa = kh.pa; kbuf->buf.blocks[i].size = kh.size; - - if (!i) { - if (kh.pa % alignment) printf("Alignment problem\n"); - else if (kh.pa & ctx->page_mask) printf("Mmap alignment problem\n"); + + if ((alignment)&&(type != PCILIB_KMEM_TYPE_PAGE)) { + if (kh.pa % alignment) kbuf->buf.blocks[i].alignment_offset = alignment - kh.pa % alignment; + kbuf->buf.blocks[i].size -= alignment; } - - addr = mmap( 0, kh.size, PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); + + addr = mmap( 0, kh.size + kbuf->buf.blocks[i].alignment_offset, PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); if ((!addr)||(addr == MAP_FAILED)) { kbuf->buf.n_blocks = i + 1; pcilib_free_kernel_memory(ctx, kbuf); @@ -71,6 +75,8 @@ pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type } kbuf->buf.blocks[i].ua = addr; + + kbuf->buf.blocks[i].mmap_offset = kh.pa & ctx->page_mask; } if (nmemb == 1) { @@ -99,7 +105,7 @@ void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k) { else if (ctx->kmem_list == kbuf) ctx->kmem_list = kbuf->next; for (i = 0; i < kbuf->buf.n_blocks; i++) { - if (kbuf->buf.blocks[i].ua) munmap(kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size); + if (kbuf->buf.blocks[i].ua) munmap(kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset); kh.handle_id = kbuf->buf.blocks[i].handle_id; kh.pa = kbuf->buf.blocks[i].pa; @@ -142,22 +148,22 @@ int pcilib_sync_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kme void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.addr.ua; + return kbuf->buf.addr.ua + kbuf->buf.addr.alignment_offset + kbuf->buf.addr.mmap_offset; } uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.addr.pa; + return kbuf->buf.addr.pa + kbuf->buf.addr.alignment_offset; } void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.blocks[block].ua; + return kbuf->buf.blocks[block].ua + kbuf->buf.blocks[block].alignment_offset + kbuf->buf.blocks[block].mmap_offset; } uintptr_t pcilib_kmem_get_block_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.blocks[block].pa; + return kbuf->buf.blocks[block].pa + kbuf->buf.blocks[block].alignment_offset; } size_t pcilib_kmem_get_block_size(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) { @@ -11,6 +11,9 @@ typedef struct { // uintptr_t va; void *ua; size_t size; + + size_t alignment_offset; + size_t mmap_offset; } pcilib_kmem_addr_t; /** |