summaryrefslogtreecommitdiffstats
path: root/driver
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
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')
-rw-r--r--driver/common.h1
-rw-r--r--driver/kmem.c36
-rw-r--r--driver/pciDriver.h1
-rw-r--r--driver/sysfs.c5
4 files changed, 32 insertions, 11 deletions
diff --git a/driver/common.h b/driver/common.h
index 5de501c..e6dea5f 100644
--- a/driver/common.h
+++ b/driver/common.h
@@ -16,6 +16,7 @@ typedef struct {
unsigned long cpua;
unsigned long size;
unsigned long type;
+ unsigned long align;
unsigned long use;
unsigned long item;
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)
diff --git a/driver/pciDriver.h b/driver/pciDriver.h
index fc92b11..3ffe8b7 100644
--- a/driver/pciDriver.h
+++ b/driver/pciDriver.h
@@ -106,6 +106,7 @@
#define KMEM_FLAG_HW 8 /**< The buffer may be accessed by hardware, the hardware access will not occur any more if passed to _free function */
#define KMEM_FLAG_FORCE 16 /**< Force memory cleanup even if references are present */
#define KMEM_FLAG_MASS 32 /**< Apply to all buffers of selected use */
+#define KMEM_FLAG_TRY 64 /**< Do not allocate buffers, try to reuse and fail if not possible */
#define KMEM_FLAG_REUSED 1 /**< Indicates if buffer with specified use & item was already allocated and reused */
#define KMEM_FLAG_REUSED_PERSISTENT 4 /**< Indicates that reused buffer was persistent before the call */
diff --git a/driver/sysfs.c b/driver/sysfs.c
index 47e4395..b10157b 100644
--- a/driver/sysfs.c
+++ b/driver/sysfs.c
@@ -101,7 +101,10 @@ static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10);
pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id);
if (entry)
- return snprintf(buf, PAGE_SIZE, "buffer: %d\ntype: %lu\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode);
+ if (entry->size >= 16)
+ return snprintf(buf, PAGE_SIZE, "buffer: %d\ntype: %lu\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n data: %8x %8x %8x %8x\n", id, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode, *(u32*)(entry->cpua), *(u32*)(entry->cpua + 4), *(u32*)(entry->cpua + 8), *(u32*)(entry->cpua + 12));
+ else
+ return snprintf(buf, PAGE_SIZE, "buffer: %d\ntype: %lu\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode);
else
return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
#else