diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 11:14:49 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 11:14:49 -0700 |
commit | b13bc8dda81c54a66a1c84e66f60b8feba659f28 (patch) | |
tree | 100a26eada424fa5d9b0e5eaaf4e23b8fa036fc8 /drivers/staging/csr/csr_msgconv.c | |
parent | Merge tag 'usb-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb (diff) | |
parent | staging: csr: delete a bunch of unused library functions (diff) | |
download | linux-dev-b13bc8dda81c54a66a1c84e66f60b8feba659f28.tar.xz linux-dev-b13bc8dda81c54a66a1c84e66f60b8feba659f28.zip |
Merge tag 'staging-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree patches from Greg Kroah-Hartman:
"Here's the big staging tree merge for the 3.6-rc1 merge window.
There are some patches in here outside of drivers/staging/, notibly
the iio code (which is still stradeling the staging / not staging
boundry), the pstore code, and the tracing code. All of these have
gotten acks from the various subsystem maintainers to be included in
this tree. The pstore and tracing patches are related, and are coming
here as they replace one of the android staging drivers.
Otherwise, the normal staging mess. Lots of cleanups and a few new
drivers (some iio drivers, and the large csr wireless driver
abomination.)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Fixed up trivial conflicts in drivers/staging/comedi/drivers/s626.h and
drivers/staging/gdm72xx/netlink_k.c
* tag 'staging-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1108 commits)
staging: csr: delete a bunch of unused library functions
staging: csr: remove csr_utf16.c
staging: csr: remove csr_pmem.h
staging: csr: remove CsrPmemAlloc
staging: csr: remove CsrPmemFree()
staging: csr: remove CsrMemAllocDma()
staging: csr: remove CsrMemCalloc()
staging: csr: remove CsrMemAlloc()
staging: csr: remove CsrMemFree() and CsrMemFreeDma()
staging: csr: remove csr_util.h
staging: csr: remove CsrOffSetOf()
stating: csr: remove unneeded #includes in csr_util.c
staging: csr: make CsrUInt16ToHex static
staging: csr: remove CsrMemCpy()
staging: csr: remove CsrStrLen()
staging: csr: remove CsrVsnprintf()
staging: csr: remove CsrStrDup
staging: csr: remove CsrStrChr()
staging: csr: remove CsrStrNCmp
staging: csr: remove CsrStrCmp
...
Diffstat (limited to 'drivers/staging/csr/csr_msgconv.c')
-rw-r--r-- | drivers/staging/csr/csr_msgconv.c | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/drivers/staging/csr/csr_msgconv.c b/drivers/staging/csr/csr_msgconv.c new file mode 100644 index 000000000000..0081a255e91c --- /dev/null +++ b/drivers/staging/csr/csr_msgconv.c @@ -0,0 +1,292 @@ +/***************************************************************************** + + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR + + Refer to LICENSE.txt included with this source for details + on the license terms. + +*****************************************************************************/ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/slab.h> +#include "csr_panic.h" +#include "csr_sched.h" +#include "csr_msgconv.h" +#include "csr_macro.h" + +static CsrMsgConvEntry *converter; + +CsrMsgConvPrimEntry *CsrMsgConvFind(u16 primType) +{ + CsrMsgConvPrimEntry *ptr = NULL; + + if (converter) + { + ptr = converter->profile_converters; + while (ptr) + { + if (ptr->primType == primType) + { + break; + } + else + { + ptr = ptr->next; + } + } + } + + return ptr; +} + +static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, u16 msgType) +{ + const CsrMsgConvMsgEntry *cv = ptr->conv; + if (ptr->lookupFunc) + { + return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType); + } + + while (cv) + { + if (cv->serFunc == NULL) + { + /* We've reached the end of the chain */ + cv = NULL; + break; + } + + if (cv->msgType == msgType) + { + break; + } + else + { + cv++; + } + } + + return cv; +} + +static void *deserialize_data(u16 primType, + size_t length, + u8 *data) +{ + CsrMsgConvPrimEntry *ptr; + u8 *ret; + + ptr = CsrMsgConvFind(primType); + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + u16 msgId = 0; + size_t offset = 0; + CsrUint16Des(&msgId, data, &offset); + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + ret = cv->deserFunc(data, length); + } + else + { + ret = NULL; + } + } + else + { + ret = NULL; + } + + return ret; +} + +static size_t sizeof_message(u16 primType, void *msg) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + size_t ret; + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + u16 msgId = *(u16 *) msg; + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + ret = cv->sizeofFunc(msg); + } + else + { + ret = 0; + } + } + else + { + ret = 0; + } + + return ret; +} + +static u8 free_message(u16 primType, u8 *data) +{ + CsrMsgConvPrimEntry *ptr; + u8 ret; + + ptr = CsrMsgConvFind(primType); + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + u16 msgId = *(u16 *) data; + + cv = find_msg_converter(ptr, msgId); + if (cv) + { + cv->freeFunc(data); + ret = TRUE; + } + else + { + ret = FALSE; + } + } + else + { + ret = FALSE; + } + + return ret; +} + +static u8 *serialize_message(u16 primType, + void *msg, + size_t *length, + u8 *buffer) +{ + CsrMsgConvPrimEntry *ptr; + u8 *ret; + + ptr = CsrMsgConvFind(primType); + + *length = 0; + + if (ptr) + { + const CsrMsgConvMsgEntry *cv; + + cv = find_msg_converter(ptr, *(u16 *) msg); + if (cv) + { + ret = cv->serFunc(buffer, length, msg); + } + else + { + ret = NULL; + } + } + else + { + ret = NULL; + } + + return ret; +} + +size_t CsrMsgConvSizeof(u16 primType, void *msg) +{ + return sizeof_message(primType, msg); +} + +u8 *CsrMsgConvSerialize(u8 *buffer, size_t maxBufferOffset, size_t *offset, u16 primType, void *msg) +{ + if (converter) + { + size_t serializedLength; + u8 *bufSerialized; + u8 *bufOffset = &buffer[*offset]; + bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset); + *offset += serializedLength; + return bufSerialized; + } + else + { + return NULL; + } +} + +/* Insert profile converter at head of converter list. */ +void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce) +{ + CsrMsgConvPrimEntry *pc; + pc = CsrMsgConvFind(primType); + + if (pc) + { + /* Already registered. Do nothing */ + } + else + { + pc = kmalloc(sizeof(*pc), GFP_KERNEL); + pc->primType = primType; + pc->conv = ce; + pc->lookupFunc = NULL; + pc->next = converter->profile_converters; + converter->profile_converters = pc; + } +} +EXPORT_SYMBOL_GPL(CsrMsgConvInsert); + +CsrMsgConvMsgEntry *CsrMsgConvFindEntry(u16 primType, u16 msgType) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr) + { + return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType); + } + return NULL; +} +EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry); + +CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr && msg) + { + u16 msgType = *((u16 *) msg); + return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType); + } + return NULL; +} + +void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc) +{ + CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType); + if (ptr) + { + ptr->lookupFunc = lookupFunc; + } +} +EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister); + +CsrMsgConvEntry *CsrMsgConvInit(void) +{ + if (!converter) + { + converter = kmalloc(sizeof(CsrMsgConvEntry), GFP_KERNEL); + + converter->profile_converters = NULL; + converter->free_message = free_message; + converter->sizeof_message = sizeof_message; + converter->serialize_message = serialize_message; + converter->deserialize_data = deserialize_data; + } + + return converter; +} +EXPORT_SYMBOL_GPL(CsrMsgConvInit); |