summaryrefslogtreecommitdiffstats
path: root/driver/kmem.c
diff options
context:
space:
mode:
authorroot <root@iss-tomyspiel-1>2011-10-21 02:37:19 +0200
committerroot <root@iss-tomyspiel-1>2011-10-21 02:37:19 +0200
commit33fb2003ef2e359f472dc153a7c2e700cdff2922 (patch)
tree102b48849f6b3a1486ac5ec5bbb305a8c8d274a1 /driver/kmem.c
parent64e0f2948b71d37e8cdb99693a00b3f440565953 (diff)
downloadipecamera-33fb2003ef2e359f472dc153a7c2e700cdff2922.tar.gz
ipecamera-33fb2003ef2e359f472dc153a7c2e700cdff2922.tar.bz2
ipecamera-33fb2003ef2e359f472dc153a7c2e700cdff2922.tar.xz
ipecamera-33fb2003ef2e359f472dc153a7c2e700cdff2922.zip
Support exporting data from kernel buffers
Diffstat (limited to 'driver/kmem.c')
-rw-r--r--driver/kmem.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/driver/kmem.c b/driver/kmem.c
index 274ab9f..afe3889 100644
--- a/driver/kmem.c
+++ b/driver/kmem.c
@@ -40,28 +40,41 @@ int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_han
if (kmem_entry) {
unsigned long flags = kmem_handle->flags;
- if (kmem_handle->type != kmem_entry->type) {
- mod_info("Invalid type of reusable kmem_entry\n");
+ if (flags&KMEM_FLAG_TRY) {
+ kmem_handle->type = kmem_entry->type;
+ kmem_handle->size = kmem_entry->size;
+ kmem_handle->align = kmem_entry->align;
+ } else {
+ if (kmem_handle->type != kmem_entry->type) {
+ mod_info("Invalid type of reusable kmem_entry\n");
return -EINVAL;
- }
+ }
- if (kmem_handle->type == PCILIB_KMEM_TYPE_PAGE) {
- kmem_handle->size = kmem_entry->size;
- } else if (kmem_handle->size != kmem_entry->size) {
+ if (kmem_handle->type == PCILIB_KMEM_TYPE_PAGE) {
+ kmem_handle->size = kmem_entry->size;
+ } else if (kmem_handle->size != kmem_entry->size) {
mod_info("Invalid size of reusable kmem_entry\n");
return -EINVAL;
- }
-
- if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)?1:0) != ((flags&KMEM_FLAG_EXCLUSIVE)?1:0)) {
+ }
+
+ if (kmem_handle->align != kmem_entry->align) {
+ mod_info("Invalid alignment of reusable kmem_entry\n");
+ return -EINVAL;
+ }
+
+ if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)?1:0) != ((flags&KMEM_FLAG_EXCLUSIVE)?1:0)) {
mod_info("Invalid mode of reusable kmem_entry\n");
return -EINVAL;
+ }
}
+
if ((kmem_entry->mode&KMEM_MODE_COUNT)==KMEM_MODE_COUNT) {
mod_info("Reuse counter of kmem_entry is overflown");
return -EBUSY;
}
+
kmem_handle->handle_id = kmem_entry->id;
kmem_handle->pa = (unsigned long)(kmem_entry->dma_handle);
@@ -79,9 +92,11 @@ int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_han
if (flags&KMEM_FLAG_PERSISTENT) kmem_entry->mode |= KMEM_MODE_PERSISTENT;
privdata->kmem_cur_id = kmem_entry->id;
-
+
return 0;
}
+
+ if (kmem_handle->flags&KMEM_FLAG_TRY) return -ENOENT;
}
/* First, allocate zeroed memory for the kmem_entry */
@@ -96,6 +111,7 @@ int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_han
kmem_entry->use = kmem_handle->use;
kmem_entry->item = kmem_handle->item;
kmem_entry->type = kmem_handle->type;
+ kmem_entry->align = kmem_handle->align;
/* Initialize sysfs if possible */
if (pcidriver_sysfs_initialize_kmem(privdata, kmem_entry->id, &(kmem_entry->sysfs_attr)) != 0)