1 /*****************************************************************************
3 (c) Cambridge Silicon Radio Limited 2010
4 All rights reserved and confidential information of CSR
6 Refer to LICENSE.txt included with this source for details
9 *****************************************************************************/
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/slab.h>
14 #include "csr_panic.h"
15 #include "csr_sched.h"
16 #include "csr_msgconv.h"
17 #include "csr_macro.h"
19 static CsrMsgConvEntry *converter;
21 CsrMsgConvPrimEntry *CsrMsgConvFind(u16 primType)
23 CsrMsgConvPrimEntry *ptr = NULL;
27 ptr = converter->profile_converters;
30 if (ptr->primType == primType)
44 static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, u16 msgType)
46 const CsrMsgConvMsgEntry *cv = ptr->conv;
49 return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType);
54 if (cv->serFunc == NULL)
56 /* We've reached the end of the chain */
61 if (cv->msgType == msgType)
74 static void *deserialize_data(u16 primType,
78 CsrMsgConvPrimEntry *ptr;
81 ptr = CsrMsgConvFind(primType);
85 const CsrMsgConvMsgEntry *cv;
88 CsrUint16Des(&msgId, data, &offset);
90 cv = find_msg_converter(ptr, msgId);
93 ret = cv->deserFunc(data, length);
108 static size_t sizeof_message(u16 primType, void *msg)
110 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
115 const CsrMsgConvMsgEntry *cv;
116 u16 msgId = *(u16 *) msg;
118 cv = find_msg_converter(ptr, msgId);
121 ret = cv->sizeofFunc(msg);
136 static u8 free_message(u16 primType, u8 *data)
138 CsrMsgConvPrimEntry *ptr;
141 ptr = CsrMsgConvFind(primType);
145 const CsrMsgConvMsgEntry *cv;
146 u16 msgId = *(u16 *) data;
148 cv = find_msg_converter(ptr, msgId);
167 static u8 *serialize_message(u16 primType,
172 CsrMsgConvPrimEntry *ptr;
175 ptr = CsrMsgConvFind(primType);
181 const CsrMsgConvMsgEntry *cv;
183 cv = find_msg_converter(ptr, *(u16 *) msg);
186 ret = cv->serFunc(buffer, length, msg);
201 size_t CsrMsgConvSizeof(u16 primType, void *msg)
203 return sizeof_message(primType, msg);
206 u8 *CsrMsgConvSerialize(u8 *buffer, size_t maxBufferOffset, size_t *offset, u16 primType, void *msg)
210 size_t serializedLength;
212 u8 *bufOffset = &buffer[*offset];
213 bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset);
214 *offset += serializedLength;
215 return bufSerialized;
223 /* Insert profile converter at head of converter list. */
224 void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce)
226 CsrMsgConvPrimEntry *pc;
227 pc = CsrMsgConvFind(primType);
231 /* Already registered. Do nothing */
235 pc = kmalloc(sizeof(*pc), GFP_KERNEL);
236 pc->primType = primType;
238 pc->lookupFunc = NULL;
239 pc->next = converter->profile_converters;
240 converter->profile_converters = pc;
243 EXPORT_SYMBOL_GPL(CsrMsgConvInsert);
245 CsrMsgConvMsgEntry *CsrMsgConvFindEntry(u16 primType, u16 msgType)
247 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
250 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
254 EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry);
256 CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg)
258 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
261 u16 msgType = *((u16 *) msg);
262 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
267 void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc)
269 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
272 ptr->lookupFunc = lookupFunc;
275 EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister);
277 CsrMsgConvEntry *CsrMsgConvInit(void)
281 converter = kmalloc(sizeof(CsrMsgConvEntry), GFP_KERNEL);
283 converter->profile_converters = NULL;
284 converter->free_message = free_message;
285 converter->sizeof_message = sizeof_message;
286 converter->serialize_message = serialize_message;
287 converter->deserialize_data = deserialize_data;
292 EXPORT_SYMBOL_GPL(CsrMsgConvInit);