Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / drivers / staging / csr / csr_msgconv.c
blob0081a255e91cdc7a332649a484c87466c9a17888
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
7 on the license terms.
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;
25 if (converter)
27 ptr = converter->profile_converters;
28 while (ptr)
30 if (ptr->primType == primType)
32 break;
34 else
36 ptr = ptr->next;
41 return ptr;
44 static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, u16 msgType)
46 const CsrMsgConvMsgEntry *cv = ptr->conv;
47 if (ptr->lookupFunc)
49 return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType);
52 while (cv)
54 if (cv->serFunc == NULL)
56 /* We've reached the end of the chain */
57 cv = NULL;
58 break;
61 if (cv->msgType == msgType)
63 break;
65 else
67 cv++;
71 return cv;
74 static void *deserialize_data(u16 primType,
75 size_t length,
76 u8 *data)
78 CsrMsgConvPrimEntry *ptr;
79 u8 *ret;
81 ptr = CsrMsgConvFind(primType);
83 if (ptr)
85 const CsrMsgConvMsgEntry *cv;
86 u16 msgId = 0;
87 size_t offset = 0;
88 CsrUint16Des(&msgId, data, &offset);
90 cv = find_msg_converter(ptr, msgId);
91 if (cv)
93 ret = cv->deserFunc(data, length);
95 else
97 ret = NULL;
100 else
102 ret = NULL;
105 return ret;
108 static size_t sizeof_message(u16 primType, void *msg)
110 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
111 size_t ret;
113 if (ptr)
115 const CsrMsgConvMsgEntry *cv;
116 u16 msgId = *(u16 *) msg;
118 cv = find_msg_converter(ptr, msgId);
119 if (cv)
121 ret = cv->sizeofFunc(msg);
123 else
125 ret = 0;
128 else
130 ret = 0;
133 return ret;
136 static u8 free_message(u16 primType, u8 *data)
138 CsrMsgConvPrimEntry *ptr;
139 u8 ret;
141 ptr = CsrMsgConvFind(primType);
143 if (ptr)
145 const CsrMsgConvMsgEntry *cv;
146 u16 msgId = *(u16 *) data;
148 cv = find_msg_converter(ptr, msgId);
149 if (cv)
151 cv->freeFunc(data);
152 ret = TRUE;
154 else
156 ret = FALSE;
159 else
161 ret = FALSE;
164 return ret;
167 static u8 *serialize_message(u16 primType,
168 void *msg,
169 size_t *length,
170 u8 *buffer)
172 CsrMsgConvPrimEntry *ptr;
173 u8 *ret;
175 ptr = CsrMsgConvFind(primType);
177 *length = 0;
179 if (ptr)
181 const CsrMsgConvMsgEntry *cv;
183 cv = find_msg_converter(ptr, *(u16 *) msg);
184 if (cv)
186 ret = cv->serFunc(buffer, length, msg);
188 else
190 ret = NULL;
193 else
195 ret = NULL;
198 return ret;
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)
208 if (converter)
210 size_t serializedLength;
211 u8 *bufSerialized;
212 u8 *bufOffset = &buffer[*offset];
213 bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset);
214 *offset += serializedLength;
215 return bufSerialized;
217 else
219 return NULL;
223 /* Insert profile converter at head of converter list. */
224 void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce)
226 CsrMsgConvPrimEntry *pc;
227 pc = CsrMsgConvFind(primType);
229 if (pc)
231 /* Already registered. Do nothing */
233 else
235 pc = kmalloc(sizeof(*pc), GFP_KERNEL);
236 pc->primType = primType;
237 pc->conv = ce;
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);
248 if (ptr)
250 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
252 return NULL;
254 EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry);
256 CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg)
258 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
259 if (ptr && msg)
261 u16 msgType = *((u16 *) msg);
262 return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
264 return NULL;
267 void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc)
269 CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
270 if (ptr)
272 ptr->lookupFunc = lookupFunc;
275 EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister);
277 CsrMsgConvEntry *CsrMsgConvInit(void)
279 if (!converter)
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;
290 return converter;
292 EXPORT_SYMBOL_GPL(CsrMsgConvInit);