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_sched.h"
15 #include "csr_msgconv.h"
16 #include "csr_macro.h"
18 static CsrMsgConvEntry *converter;
20 CsrMsgConvPrimEntry *CsrMsgConvFind(u16 primType)
22 CsrMsgConvPrimEntry *ptr = NULL;
26 ptr = converter->profile_converters;
29 if (ptr->primType == primType)
43 static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, u16 msgType)
45 const CsrMsgConvMsgEntry *cv = ptr->conv;
48 return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType);
53 if (cv->serFunc == NULL)
55 /* We've reached the end of the chain */
60 if (cv->msgType == msgType)
73 static void *deserialize_data(u16 primType,
77 CsrMsgConvPrimEntry *ptr;
80 ptr = CsrMsgConvFind(primType);
84 const CsrMsgConvMsgEntry *cv;
87 CsrUint16Des(&msgId, data, &offset);
89 cv = find_msg_converter(ptr, msgId);
92 ret = cv->deserFunc(data, length);
107 static size_t sizeof_message(u16 primType, void *msg)
109 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
114 const CsrMsgConvMsgEntry *cv;
115 u16 msgId = *(u16 *) msg;
117 cv = find_msg_converter(ptr, msgId);
120 ret = cv->sizeofFunc(msg);
135 static u8 free_message(u16 primType, u8 *data)
137 CsrMsgConvPrimEntry *ptr;
140 ptr = CsrMsgConvFind(primType);
144 const CsrMsgConvMsgEntry *cv;
145 u16 msgId = *(u16 *) data;
147 cv = find_msg_converter(ptr, msgId);
166 static u8 *serialize_message(u16 primType,
171 CsrMsgConvPrimEntry *ptr;
174 ptr = CsrMsgConvFind(primType);
180 const CsrMsgConvMsgEntry *cv;
182 cv = find_msg_converter(ptr, *(u16 *) msg);
185 ret = cv->serFunc(buffer, length, msg);
200 size_t CsrMsgConvSizeof(u16 primType, void *msg)
202 return sizeof_message(primType, msg);
205 u8 *CsrMsgConvSerialize(u8 *buffer, size_t maxBufferOffset, size_t *offset, u16 primType, void *msg)
209 size_t serializedLength;
211 u8 *bufOffset = &buffer[*offset];
212 bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset);
213 *offset += serializedLength;
214 return bufSerialized;
222 /* Insert profile converter at head of converter list. */
223 void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce)
225 CsrMsgConvPrimEntry *pc;
226 pc = CsrMsgConvFind(primType);
230 /* Already registered. Do nothing */
234 pc = kmalloc(sizeof(*pc), GFP_KERNEL);
235 pc->primType = primType;
237 pc->lookupFunc = NULL;
238 pc->next = converter->profile_converters;
239 converter->profile_converters = pc;
242 EXPORT_SYMBOL_GPL(CsrMsgConvInsert);
244 CsrMsgConvMsgEntry *CsrMsgConvFindEntry(u16 primType, u16 msgType)
246 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
249 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
253 EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry);
255 CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg)
257 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
260 u16 msgType = *((u16 *) msg);
261 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
266 void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc)
268 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
271 ptr->lookupFunc = lookupFunc;
274 EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister);
276 CsrMsgConvEntry *CsrMsgConvInit(void)
280 converter = kmalloc(sizeof(CsrMsgConvEntry), GFP_KERNEL);
282 converter->profile_converters = NULL;
283 converter->free_message = free_message;
284 converter->sizeof_message = sizeof_message;
285 converter->serialize_message = serialize_message;
286 converter->deserialize_data = deserialize_data;
291 EXPORT_SYMBOL_GPL(CsrMsgConvInit);