2 #include "wilc_msgqueue.h"
3 #include <linux/spinlock.h>
8 * @note copied from FLO glue implementatuion
11 WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle)
13 spin_lock_init(&pHandle->strCriticalSection);
14 sema_init(&pHandle->hSem, 0);
15 pHandle->pstrMessageList = NULL;
16 pHandle->u32ReceiversCount = 0;
17 pHandle->bExiting = false;
24 * @note copied from FLO glue implementatuion
27 WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle)
30 pHandle->bExiting = true;
32 /* Release any waiting receiver thread. */
33 while (pHandle->u32ReceiversCount > 0) {
35 pHandle->u32ReceiversCount--;
38 while (pHandle->pstrMessageList != NULL) {
39 Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
40 kfree(pHandle->pstrMessageList);
41 pHandle->pstrMessageList = pstrMessge;
50 * @note copied from FLO glue implementatuion
53 WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
54 const void *pvSendBuffer, u32 u32SendBufferSize)
56 WILC_ErrNo s32RetStatus = WILC_SUCCESS;
58 Message *pstrMessage = NULL;
60 if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) {
61 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
64 if (pHandle->bExiting == true) {
65 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
68 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
70 /* construct a new message */
71 pstrMessage = kmalloc(sizeof(Message), GFP_ATOMIC);
72 WILC_NULLCHECK(s32RetStatus, pstrMessage);
73 pstrMessage->u32Length = u32SendBufferSize;
74 pstrMessage->pstrNext = NULL;
75 pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize);
76 WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
77 memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
80 /* add it to the message queue */
81 if (pHandle->pstrMessageList == NULL) {
82 pHandle->pstrMessageList = pstrMessage;
84 Message *pstrTailMsg = pHandle->pstrMessageList;
85 while (pstrTailMsg->pstrNext != NULL) {
86 pstrTailMsg = pstrTailMsg->pstrNext;
88 pstrTailMsg->pstrNext = pstrMessage;
91 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
95 WILC_CATCH(s32RetStatus)
97 /* error occured, free any allocations */
98 if (pstrMessage != NULL) {
99 if (pstrMessage->pvBuffer != NULL) {
100 kfree(pstrMessage->pvBuffer);
114 * @note copied from FLO glue implementatuion
117 WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
118 void *pvRecvBuffer, u32 u32RecvBufferSize,
119 u32 *pu32ReceivedLength)
122 Message *pstrMessage;
123 WILC_ErrNo s32RetStatus = WILC_SUCCESS;
125 if ((pHandle == NULL) || (u32RecvBufferSize == 0)
126 || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) {
127 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
130 if (pHandle->bExiting == true) {
131 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
134 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
135 pHandle->u32ReceiversCount++;
136 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
138 down(&(pHandle->hSem));
140 if (s32RetStatus == WILC_TIMEOUT) {
141 /* timed out, just exit without consumeing the message */
142 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
143 pHandle->u32ReceiversCount--;
144 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
146 /* other non-timeout scenarios */
147 WILC_ERRORCHECK(s32RetStatus);
149 if (pHandle->bExiting) {
150 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
153 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
155 pstrMessage = pHandle->pstrMessageList;
156 if (pstrMessage == NULL) {
157 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
158 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
160 /* check buffer size */
161 if (u32RecvBufferSize < pstrMessage->u32Length) {
162 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
164 WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW);
167 /* consume the message */
168 pHandle->u32ReceiversCount--;
169 memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
170 *pu32ReceivedLength = pstrMessage->u32Length;
172 pHandle->pstrMessageList = pstrMessage->pstrNext;
174 kfree(pstrMessage->pvBuffer);
177 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
181 WILC_CATCH(s32RetStatus)