summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Tivy <rtivy@ti.com>2014-01-17 17:25:49 -0800
committerChris Ring <cring@ti.com>2014-01-21 08:22:29 -0800
commit317792d2c18c1144401e2aee689aadebbd3a9b12 (patch)
treedad587bb0b62b8d1b06025d46d2612678a6e5c58
parentc6080eb94fea4c243b7802b1ea2cff4c34319a27 (diff)
downloadlinuxutils-317792d2c18c1144401e2aee689aadebbd3a9b12.tar.gz
Allow bigger sizes for CMEM_getBlock and CMEM_getPool4.00.02.114.00.02.10_eng
CMEM_getBlock() (and CMEM_getBlockAttrs) was broken for the new extended blocks. The interface has been changed to allow for returning a size greater than the value that will fit in a 'size_t' type. CMEM_getPool() did not allow a size greater than the value that will fit in a 'size_t' type. This API has been changed to allow specifying an extended size, to support pools with an extended buffer size.
-rw-r--r--include/ti/cmem.h16
-rw-r--r--src/cmem/api/cmem.c48
-rw-r--r--src/cmem/module/cmemk.c55
-rw-r--r--src/cmem/tests/apitest.c39
4 files changed, 89 insertions, 69 deletions
diff --git a/include/ti/cmem.h b/include/ti/cmem.h
index 6174d37..ae00753 100644
--- a/include/ti/cmem.h
+++ b/include/ti/cmem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -296,7 +296,7 @@ extern CMEM_AllocParams CMEM_DEFAULTPARAMS;
typedef struct CMEM_BlockAttrs {
off_t phys_base;
- size_t size;
+ unsigned long long size;
} CMEM_BlockAttrs;
/** @cond INTERNAL */
@@ -318,16 +318,16 @@ union CMEM_AllocUnion {
int blockid;
} get_size_inparams; /**< */
struct { /**< */
- size_t size;
+ unsigned long long size;
int blockid;
} get_pool_inparams; /**< */
struct { /**< */
unsigned long long physp;
- size_t size;
+ unsigned long long size;
} alloc_pool_outparams; /**< */
struct { /**< */
unsigned long long physp;
- size_t size;
+ unsigned long long size;
} get_block_outparams; /**< */
struct { /**< */
int poolid;
@@ -366,7 +366,7 @@ int CMEM_init(void);
* @sa CMEM_free()
* @sa CMEM_getPool2()
*/
-int CMEM_getPool(size_t size);
+int CMEM_getPool(unsigned long long size);
/**
* @brief Find the pool in memory block blockid that best fits a given
@@ -384,7 +384,7 @@ int CMEM_getPool(size_t size);
* @sa CMEM_free()
* @sa CMEM_getPool()
*/
-int CMEM_getPool2(int blockid, size_t size);
+int CMEM_getPool2(int blockid, unsigned long long size);
/**
* @brief Allocate memory from a specified pool.
@@ -797,7 +797,7 @@ int CMEM_getVersion(void);
* @sa CMEM_getBlockAttrs()
* @sa CMEM_getNumBlocks()
*/
-int CMEM_getBlock(off_t *pphys_base, size_t *psize);
+int CMEM_getBlock(off_t *pphys_base, unsigned long long *psize);
/**
* @brief Retrieve extended memory block attributes from CMEM driver
diff --git a/src/cmem/api/cmem.c b/src/cmem/api/cmem.c
index 6853a17..c4140ec 100644
--- a/src/cmem/api/cmem.c
+++ b/src/cmem/api/cmem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -67,7 +67,7 @@ struct block_struct {
static int cmem_fd = -2;
static int ref_count = 0;
-static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp);
+static void *getAndAllocFromPool(int blockid, unsigned long long size, CMEM_AllocParams *params, off_t *physp);
static void *allocFromHeap(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp);
static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, off_t *physp);
@@ -158,7 +158,8 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of
union CMEM_AllocUnion allocDesc;
off_t phys;
void *userp;
- size_t size;
+ unsigned long long size;
+ size_t map_size;
unsigned int cmd;
int rv;
@@ -179,7 +180,7 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of
phys = (off_t)allocDesc.alloc_pool_outparams.physp;
size = allocDesc.alloc_pool_outparams.size;
- __D("allocPool: allocated phys buffer %#llx, size %#x\n",
+ __D("allocPool: allocated phys buffer %#llx, size %#llx\n",
(unsigned long long)phys, size);
/* non-NULL physp means "don't map", return NULL since no virt ptr */
@@ -188,13 +189,22 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of
return NULL;
}
+ map_size = (size_t)size;
+ if (map_size != size) {
+ __E("allocPool: returned pool buffer too big for mmap (size %#llx)\n",
+ size);
+ __E(" Freeing phys buffer %#llx\n", (unsigned long long)phys);
+ ioctl(cmem_fd, CMEM_IOCFREEPHYS | CMEM_IOCMAGIC , &phys);
+ return NULL;
+ }
+
/* Map the physical address to user space */
userp = mmap(0, // Preferred start address
- size, // Length to be mapped
+ map_size, // Length to be mapped
PROT_WRITE | PROT_READ, // Read and write access
MAP_SHARED, // Shared memory
cmem_fd, // File descriptor
- phys); // The byte offset from fd
+ phys); // The byte offset from fd
if (userp == MAP_FAILED) {
__E("allocPool: Failed to mmap buffer at physical address %#llx\n",
@@ -209,7 +219,7 @@ static void *allocFromPool(int blockid, int poolid, CMEM_AllocParams *params, of
return userp;
}
-static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *params, off_t *physp)
+static void *getAndAllocFromPool(int blockid, unsigned long long size, CMEM_AllocParams *params, off_t *physp)
{
int poolid;
@@ -223,7 +233,7 @@ static void *getAndAllocFromPool(int blockid, size_t size, CMEM_AllocParams *par
return NULL;
}
if (poolid == -2) {
- return allocFromHeap(blockid, size, params, physp);
+ return allocFromHeap(blockid, (size_t)size, params, physp);
}
else {
return allocFromPool(blockid, poolid, params, physp);
@@ -316,7 +326,7 @@ static void *alloc(int blockid, size_t size, CMEM_AllocParams *params, off_t *ph
}
if (params->type == CMEM_POOL) {
- return getAndAllocFromPool(blockid, size, params, physp);
+ return getAndAllocFromPool(blockid, (unsigned long long)size, params, physp);
}
else {
return allocFromHeap(blockid, size, params, physp);
@@ -554,7 +564,7 @@ int CMEM_unregister(void *ptr, CMEM_AllocParams *params)
return CMEM_free(ptr, params);
}
-static int getPoolFromBlock(int blockid, size_t size)
+static int getPoolFromBlock(int blockid, unsigned long long size)
{
union CMEM_AllocUnion poolDesc;
@@ -565,7 +575,7 @@ static int getPoolFromBlock(int blockid, size_t size)
poolDesc.get_pool_inparams.size = size;
poolDesc.get_pool_inparams.blockid = blockid;
if (ioctl(cmem_fd, CMEM_IOCGETPOOL | CMEM_IOCMAGIC, &poolDesc) == -1) {
- __E("getPool: Failed to get a pool fitting a size %d\n", size);
+ __E("getPool: Failed to get a pool fitting a size %#llx\n", size);
return -1;
}
@@ -575,16 +585,16 @@ static int getPoolFromBlock(int blockid, size_t size)
return poolDesc.poolid;
}
-int CMEM_getPool(size_t size)
+int CMEM_getPool(unsigned long long size)
{
- __D("getPool: entered w/ size %#x\n", size);
+ __D("getPool: entered w/ size %#llx\n", size);
return getPoolFromBlock(0, size);
}
-int CMEM_getPool2(int blockid, size_t size)
+int CMEM_getPool2(int blockid, unsigned long long size)
{
- __D("getPool2: entered w/ size %#x\n", size);
+ __D("getPool2: entered w/ size %#llx\n", size);
return getPoolFromBlock(blockid, size);
}
@@ -706,7 +716,7 @@ int CMEM_getVersion(void)
return version;
}
-static int getBlock(int blockid, off_t *pphys_base, size_t *psize)
+static int getBlock(int blockid, off_t *pphys_base, unsigned long long *psize)
{
union CMEM_AllocUnion block;
int rv;
@@ -730,13 +740,13 @@ static int getBlock(int blockid, off_t *pphys_base, size_t *psize)
*psize = block.get_block_outparams.size;
__D("getBlock: exiting, ioctl CMEM_IOCGETBLOCK succeeded, "
- "returning *pphys_base=%#llx, *psize=%#x\n",
+ "returning *pphys_base=%#llx, *psize=%#llx\n",
(unsigned long long)(*pphys_base), *psize);
return 0;
}
-int CMEM_getBlock(off_t *pphys_base, size_t *psize)
+int CMEM_getBlock(off_t *pphys_base, unsigned long long *psize)
{
return getBlock(0, pphys_base, psize);
}
@@ -758,7 +768,7 @@ int CMEM_getNumBlocks(int *pnblocks)
rv = ioctl(cmem_fd, CMEM_IOCGETNUMBLOCKS | CMEM_IOCMAGIC, pnblocks);
if (rv != 0) {
- __E("getBlock: Failed to retrieve number of blocks "
+ __E("getNumBlocks: Failed to retrieve number of blocks "
"from driver: %d.\n", rv);
return -1;
diff --git a/src/cmem/module/cmemk.c b/src/cmem/module/cmemk.c
index cf968a2..7cf86af 100644
--- a/src/cmem/module/cmemk.c
+++ b/src/cmem/module/cmemk.c
@@ -1165,7 +1165,8 @@ static long ioctl(struct file *filp, unsigned int cmd, unsigned long args)
dma_addr_t dma = 0;
size_t reqsize, align;
size_t size = 0;
- int delta = MAXTYPE(int);
+ unsigned long long lsize, lreqsize;
+ unsigned long long delta = MAXTYPE(unsigned long long);
int pool = -1;
int i;
int bi;
@@ -1290,7 +1291,7 @@ alloc:
}
__D("ALLOCHEAP%s: allocated %#x size buffer at %#llx (phys address)\n",
- cmd & CMEM_CACHED ? "CACHED" : "", entry->size,
+ cmd & CMEM_CACHED ? "CACHED" : "", (size_t)entry->size,
(unsigned long long)entry->physp);
break;
@@ -1327,7 +1328,7 @@ alloc:
}
if (bi == NBLOCKS) {
- size = p_objs[bi][pool].size;
+ lsize = p_objs[bi][pool].size;
dev = &cmem_cma_dev[pool];
align = 0;
pool_alloc = 1;
@@ -1427,7 +1428,7 @@ alloc:
if (entry) {
/* record values in case entry gets kfree()'d for CMEM_HEAP */
id = entry->id;
- size = entry->size;
+ size = (size_t)entry->size;
registeredlistp = &entry->users;
u = registeredlistp->next;
@@ -1483,11 +1484,11 @@ alloc:
}
if (bi == NBLOCKS) {
- dma_free_coherent(entry->dev, entry->size,
+ dma_free_coherent(entry->dev, (size_t)entry->size,
entry->kvirtp, entry->dma);
}
else {
- HeapMem_free(bi, entry->physp, entry->size);
+ HeapMem_free(bi, entry->physp, (size_t)entry->size);
}
list_del(e);
kfree(entry);
@@ -1594,7 +1595,7 @@ alloc:
if (put_user(p_objs[bi][pool].size, argp)) {
return -EFAULT;
}
- __D("GETSIZE returning %d\n", p_objs[bi][pool].size);
+ __D("GETSIZE returning %#llx\n", p_objs[bi][pool].size);
break;
/*
@@ -1607,7 +1608,7 @@ alloc:
return -EFAULT;
}
- reqsize = allocDesc.get_pool_inparams.size;
+ lreqsize = allocDesc.get_pool_inparams.size;
bi = allocDesc.get_pool_inparams.blockid;
if (bi == CMEM_CMABLOCKID) {
@@ -1624,28 +1625,29 @@ alloc:
return -ERESTARTSYS;
}
- __D("GETPOOL: Trying to find a pool to fit size %d\n", reqsize);
+ __D("GETPOOL: Trying to find a pool to fit size %#llx\n", lreqsize);
for (i = 0; i < npools[bi]; i++) {
- size = p_objs[bi][i].size;
+ lsize = p_objs[bi][i].size;
freelistp = &p_objs[bi][i].freelist;
- __D("GETPOOL: size (%d) > reqsize (%d)?\n", size, reqsize);
- if (size >= reqsize) {
- __D("GETPOOL: delta (%d) < olddelta (%d)?\n",
- size - reqsize, delta);
- if ((size - reqsize) < delta) {
+ __D("GETPOOL: size (%#llx) > reqsize (%#llx)?\n",
+ lsize, lreqsize);
+ if (lsize >= lreqsize) {
+ __D("GETPOOL: delta (%#llx) < olddelta (%#llx)?\n",
+ lsize - lreqsize, delta);
+ if ((lsize - lreqsize) < delta) {
if (bi < NBLOCKS) {
if (!list_empty(freelistp)) {
- delta = size - reqsize;
+ delta = lsize - lreqsize;
pool = i;
- __D("GETPOOL: Found a best fit delta %d in pool %d\n",
+ __D("GETPOOL: Found a best fit delta %#llx in pool %d\n",
delta, pool);
}
}
else {
- delta = size - reqsize;
+ delta = lsize - lreqsize;
pool = i;
- __D("GETPOOL: Found a best fit delta %d in CMA block\n",
+ __D("GETPOOL: Found a best fit delta %#llx in CMA block\n",
delta);
}
}
@@ -1656,6 +1658,7 @@ alloc:
if (useHeapIfPoolUnavailable) {
/* no pool buffer available, try heap */
+ reqsize = lreqsize;
physp = HeapMem_alloc(bi, reqsize, HEAP_ALIGN, DRYRUN);
if (physp != 0) {
/*
@@ -1675,7 +1678,7 @@ alloc:
mutex_unlock(&cmem_mutex);
if (pool == -1) {
- __E("Failed to find a pool which fits %d\n", reqsize);
+ __E("Failed to find a pool which fits %#llx\n", lreqsize);
return -ENOMEM;
}
@@ -1814,7 +1817,7 @@ alloc:
block_start[bi];
__D("GETBLOCK: returning phys base "
- "%#llx, size %#x.\n", allocDesc.get_block_outparams.physp,
+ "%#llx, size %#llx.\n", allocDesc.get_block_outparams.physp,
allocDesc.get_block_outparams.size);
if (copy_to_user(argp, &allocDesc, sizeof(allocDesc))) {
@@ -1886,11 +1889,12 @@ static int mmap(struct file *filp, struct vm_area_struct *vma)
{
phys_addr_t physp;
struct pool_buffer *entry;
- size_t size = vma->vm_end - vma->vm_start;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ size_t s;
__D("mmap: vma->vm_start = %#lx\n", vma->vm_start);
__D("mmap: vma->vm_end = %#lx\n", vma->vm_end);
- __D("mmap: size = %#llx\n", (unsigned long long)size);
+ __D("mmap: size = %#lx\n", size);
__D("mmap: vma->vm_pgoff = %#lx\n", vma->vm_pgoff);
physp = (unsigned long long)vma->vm_pgoff << PAGE_SHIFT;
@@ -1899,7 +1903,8 @@ static int mmap(struct file *filp, struct vm_area_struct *vma)
return -ERESTARTSYS;
}
- entry = find_busy_entry(physp, NULL, NULL, NULL, &size);
+ s = size;
+ entry = find_busy_entry(physp, NULL, NULL, NULL, &s);
mutex_unlock(&cmem_mutex);
if (entry != NULL) {
@@ -2349,7 +2354,7 @@ int __init cmem_init(void)
cmem_cma_dev[i].coherent_dma_mask = DMA_BIT_MASK(32);
- __D(" pool %d: size=%#x numbufs=%d\n", i,
+ __D(" pool %d: size=%#llx numbufs=%d\n", i,
p_objs[NBLOCKS][i].size, p_objs[NBLOCKS][i].numbufs);
}
diff --git a/src/cmem/tests/apitest.c b/src/cmem/tests/apitest.c
index dc48e20..750f211 100644
--- a/src/cmem/tests/apitest.c
+++ b/src/cmem/tests/apitest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007-2013 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (c) 2007-2014 Texas Instruments Incorporated - http://www.ti.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -54,7 +54,7 @@
unsigned int *ptrs[NUMHEAPPTRS];
int nblocks;
-int writereadCMA(int size)
+int writereadCMA(size_t size)
{
int rv;
int i;
@@ -107,7 +107,7 @@ int writereadCMA(int size)
return 0;
}
-void testCMA(int size)
+void testCMA(size_t size)
{
int rv;
int num_buffers;
@@ -169,7 +169,7 @@ void testCMA(int size)
}
-void testHeap(int size, int block)
+void testHeap(size_t size, int block)
{
int rv;
int num_buffers;
@@ -225,7 +225,7 @@ void testHeap(int size, int block)
printf("...done\n");
}
-void testPools(int size, int block)
+void testPools(size_t size, int block)
{
int rv;
int num_buffers;
@@ -281,7 +281,7 @@ void testPools(int size, int block)
printf("...done\n");
}
-void testCache(int size, int block)
+void testCache(size_t size, int block)
{
unsigned int *ptr1_nocache = NULL;
unsigned int *ptr1_cache = NULL;
@@ -324,7 +324,7 @@ void testCache(int size, int block)
(unsigned long long)physp_nocache);
/* Write some data into this buffer */
- for (i=0; i < size / sizeof(int) ; i++) {
+ for (i=0; i < size / sizeof(size_t) ; i++) {
ptr1_nocache[i] = 0xbeefbeef;
}
@@ -356,7 +356,7 @@ void testCache(int size, int block)
(unsigned long long)physp_cache);
/* Write some data into this buffer */
- for (i = 0; i < size / sizeof(int); i++) {
+ for (i = 0; i < size / sizeof(size_t); i++) {
ptr1_cache[i] = 0x0dead1ce;
}
@@ -386,7 +386,7 @@ void testCache(int size, int block)
(unsigned long long)physp_dma);
/* Initialize DMA source buffer */
- for (i = 0; i < size / sizeof(int); i++) {
+ for (i = 0; i < size / sizeof(size_t); i++) {
ptr1_cache[i] = 0x0dead1ce;
}
@@ -399,7 +399,7 @@ void testCache(int size, int block)
printf("R-M-W noncached buffer %#llx\n",
(unsigned long long)physp_nocache);
gettimeofday(&start_tv, NULL);
- for (i = 0; i < (size / sizeof(int)); i += 1) {
+ for (i = 0; i < (size / sizeof(size_t)); i += 1) {
ptr1_nocache[i] += 1;
}
gettimeofday(&end_tv, NULL);
@@ -411,7 +411,7 @@ void testCache(int size, int block)
printf("R-M-W cached buffer %#llx\n", (unsigned long long)physp_cache);
gettimeofday(&start_tv, NULL);
- for (i = 0; i < (size / sizeof(int)); i += 1) {
+ for (i = 0; i < (size / sizeof(size_t)); i += 1) {
ptr1_cache[i] += 1;
}
gettimeofday(&end_tv, NULL);
@@ -435,7 +435,7 @@ void testCache(int size, int block)
printf("R-M-W cached buffer %#llx\n", (unsigned long long)physp_cache);
gettimeofday(&start_tv, NULL);
- for (i = 0; i < (size / sizeof(int)); i += 1) {
+ for (i = 0; i < (size / sizeof(size_t)); i += 1) {
ptr1_cache[i] += 1;
}
gettimeofday(&end_tv, NULL);
@@ -485,7 +485,7 @@ void testCache(int size, int block)
(unsigned long long)physp);
/* Write some data into this buffer */
- for (i=0; i < size / sizeof(int); i++) {
+ for (i=0; i < size / sizeof(size_t); i++) {
ptr2[i] = 0xfeebfeeb;
}
@@ -532,7 +532,7 @@ cleanup:
}
}
-int testMap(int size)
+int testMap(size_t size)
{
int *ptr;
int *map_ptr;
@@ -542,6 +542,11 @@ int testMap(int size)
ptr = CMEM_alloc(size, NULL);
printf("testMap: ptr = %p\n", ptr);
+ if (ptr == NULL) {
+ printf("testMap: CMEM_alloc() failed\n");
+ return 1;
+ }
+
printf(" writing 0xdadaface to *ptr\n");
*ptr = 0xdadaface;
@@ -588,7 +593,7 @@ cleanup:
return ret;
}
-int testAllocPhys(int size)
+int testAllocPhys(size_t size)
{
int *map_ptr;
off_t physp;
@@ -634,7 +639,7 @@ cleanup:
int main(int argc, char *argv[])
{
- int size;
+ size_t size;
int version;
CMEM_BlockAttrs attrs;
int i;
@@ -685,7 +690,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failed to retrieve CMEM memory block %d bounds\n", i);
}
else {
- printf("CMEM memory block %d: phys start = %#llx, size = %#x\n",
+ printf("CMEM memory block %d: phys start = %#llx, size = %#llx\n",
i, (unsigned long long)attrs.phys_base, attrs.size);
}