2 #include "wilc_msgqueue.h"
3 #include <linux/spinlock.h>
4 #include "linux_wlan_common.h"
5 #include <linux/errno.h>
6 #include <linux/slab.h>
11 * @note copied from FLO glue implementatuion
14 int wilc_mq_create(WILC_MsgQueueHandle *pHandle)
16 spin_lock_init(&pHandle->strCriticalSection);
17 sema_init(&pHandle->hSem, 0);
18 pHandle->pstrMessageList = NULL;
19 pHandle->u32ReceiversCount = 0;
20 pHandle->bExiting = false;
27 * @note copied from FLO glue implementatuion
30 int wilc_mq_destroy(WILC_MsgQueueHandle *pHandle)
32 pHandle->bExiting = true;
34 /* Release any waiting receiver thread. */
35 while (pHandle->u32ReceiversCount > 0) {
37 pHandle->u32ReceiversCount--;
40 while (pHandle->pstrMessageList) {
41 Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
43 kfree(pHandle->pstrMessageList);
44 pHandle->pstrMessageList = pstrMessge;
53 * @note copied from FLO glue implementatuion
56 int wilc_mq_send(WILC_MsgQueueHandle *pHandle,
57 const void *pvSendBuffer, u32 u32SendBufferSize)
61 Message *pstrMessage = NULL;
63 if ((!pHandle) || (u32SendBufferSize == 0) || (!pvSendBuffer)) {
64 PRINT_ER("pHandle or pvSendBuffer is null\n");
69 if (pHandle->bExiting) {
70 PRINT_ER("pHandle fail\n");
75 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
77 /* construct a new message */
78 pstrMessage = kmalloc(sizeof(Message), GFP_ATOMIC);
81 pstrMessage->u32Length = u32SendBufferSize;
82 pstrMessage->pstrNext = NULL;
83 pstrMessage->pvBuffer = kmalloc(u32SendBufferSize, GFP_ATOMIC);
84 if (!pstrMessage->pvBuffer) {
88 memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
90 /* add it to the message queue */
91 if (!pHandle->pstrMessageList) {
92 pHandle->pstrMessageList = pstrMessage;
94 Message *pstrTailMsg = pHandle->pstrMessageList;
96 while (pstrTailMsg->pstrNext)
97 pstrTailMsg = pstrTailMsg->pstrNext;
99 pstrTailMsg->pstrNext = pstrMessage;
102 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
107 /* error occured, free any allocations */
109 kfree(pstrMessage->pvBuffer);
119 * @note copied from FLO glue implementatuion
122 int wilc_mq_recv(WILC_MsgQueueHandle *pHandle,
123 void *pvRecvBuffer, u32 u32RecvBufferSize,
124 u32 *pu32ReceivedLength)
126 Message *pstrMessage;
130 if ((!pHandle) || (u32RecvBufferSize == 0)
131 || (!pvRecvBuffer) || (!pu32ReceivedLength)) {
132 PRINT_ER("pHandle or pvRecvBuffer is null\n");
136 if (pHandle->bExiting) {
137 PRINT_ER("pHandle fail\n");
141 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
142 pHandle->u32ReceiversCount++;
143 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
145 down(&pHandle->hSem);
147 /* other non-timeout scenarios */
149 PRINT_ER("Non-timeout\n");
153 if (pHandle->bExiting) {
154 PRINT_ER("pHandle fail\n");
158 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
160 pstrMessage = pHandle->pstrMessageList;
162 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
163 PRINT_ER("pstrMessage is null\n");
166 /* check buffer size */
167 if (u32RecvBufferSize < pstrMessage->u32Length) {
168 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
170 PRINT_ER("u32RecvBufferSize overflow\n");
174 /* consume the message */
175 pHandle->u32ReceiversCount--;
176 memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
177 *pu32ReceivedLength = pstrMessage->u32Length;
179 pHandle->pstrMessageList = pstrMessage->pstrNext;
181 kfree(pstrMessage->pvBuffer);
184 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);