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
);