From 33fb2003ef2e359f472dc153a7c2e700cdff2922 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 21 Oct 2011 02:37:19 +0200 Subject: Support exporting data from kernel buffers --- driver/common.h | 1 + driver/kmem.c | 36 ++++++++++++++++++++++++++---------- driver/pciDriver.h | 1 + driver/sysfs.c | 5 ++++- 4 files changed, 32 insertions(+), 11 deletions(-) (limited to 'driver') 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 -- cgit v1.2.3