summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-06 03:48:40 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-06 03:48:40 +0200
commit5c1e2da736a77fc7172da2c621310a9ceaf1e6ce (patch)
tree98d18bc0e62de19b9bfac0100183dc630a3999dd
parente78aba2587be9e79e73ba3275b6c9b2de3c5c71a (diff)
downloadipecamera-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.gz
ipecamera-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.bz2
ipecamera-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.tar.xz
ipecamera-5c1e2da736a77fc7172da2c621310a9ceaf1e6ce.zip
Support alignments in kmem allocation
-rw-r--r--dma/nwl.c2
-rw-r--r--kmem.c28
-rw-r--r--kmem.h3
3 files changed, 21 insertions, 12 deletions
diff --git a/dma/nwl.c b/dma/nwl.c
index ee74a95..32cc2db 100644
--- a/dma/nwl.c
+++ b/dma/nwl.c
@@ -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;
diff --git a/kmem.c b/kmem.c
index 8388f2a..10bd88c 100644
--- a/kmem.c
+++ b/kmem.c
@@ -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) {
diff --git a/kmem.h b/kmem.h
index 985864d..a92d55a 100644
--- a/kmem.h
+++ b/kmem.h
@@ -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;
/**