]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/wilc_msgqueue.c
staging: wilc1000: remove unneeded tstrWILC_MsgQueueAttrs typedef
[karo-tx-linux.git] / drivers / staging / wilc1000 / wilc_msgqueue.c
1
2 #include "wilc_msgqueue.h"
3 #include <linux/spinlock.h>
4
5 /*!
6  *  @author             syounan
7  *  @date               1 Sep 2010
8  *  @note               copied from FLO glue implementatuion
9  *  @version            1.0
10  */
11 WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle)
12 {
13         spin_lock_init(&pHandle->strCriticalSection);
14         sema_init(&pHandle->hSem, 0);
15         pHandle->pstrMessageList = NULL;
16         pHandle->u32ReceiversCount = 0;
17         pHandle->bExiting = false;
18         return WILC_SUCCESS;
19 }
20
21 /*!
22  *  @author             syounan
23  *  @date               1 Sep 2010
24  *  @note               copied from FLO glue implementatuion
25  *  @version            1.0
26  */
27 WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle)
28 {
29
30         pHandle->bExiting = true;
31
32         /* Release any waiting receiver thread. */
33         while (pHandle->u32ReceiversCount > 0) {
34                 up(&(pHandle->hSem));
35                 pHandle->u32ReceiversCount--;
36         }
37
38         while (pHandle->pstrMessageList != NULL) {
39                 Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
40                 kfree(pHandle->pstrMessageList);
41                 pHandle->pstrMessageList = pstrMessge;
42         }
43
44         return WILC_SUCCESS;
45 }
46
47 /*!
48  *  @author             syounan
49  *  @date               1 Sep 2010
50  *  @note               copied from FLO glue implementatuion
51  *  @version            1.0
52  */
53 WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
54                              const void *pvSendBuffer, u32 u32SendBufferSize)
55 {
56         WILC_ErrNo s32RetStatus = WILC_SUCCESS;
57         unsigned long flags;
58         Message *pstrMessage = NULL;
59
60         if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) {
61                 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
62         }
63
64         if (pHandle->bExiting == true) {
65                 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
66         }
67
68         spin_lock_irqsave(&pHandle->strCriticalSection, flags);
69
70         /* construct a new message */
71         pstrMessage = WILC_NEW(Message, 1);
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);
78
79
80         /* add it to the message queue */
81         if (pHandle->pstrMessageList == NULL) {
82                 pHandle->pstrMessageList  = pstrMessage;
83         } else {
84                 Message *pstrTailMsg = pHandle->pstrMessageList;
85                 while (pstrTailMsg->pstrNext != NULL) {
86                         pstrTailMsg = pstrTailMsg->pstrNext;
87                 }
88                 pstrTailMsg->pstrNext = pstrMessage;
89         }
90
91         spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
92
93         up(&pHandle->hSem);
94
95         WILC_CATCH(s32RetStatus)
96         {
97                 /* error occured, free any allocations */
98                 if (pstrMessage != NULL) {
99                         if (pstrMessage->pvBuffer != NULL) {
100                                 kfree(pstrMessage->pvBuffer);
101                         }
102                         kfree(pstrMessage);
103                 }
104         }
105
106         return s32RetStatus;
107 }
108
109
110
111 /*!
112  *  @author             syounan
113  *  @date               1 Sep 2010
114  *  @note               copied from FLO glue implementatuion
115  *  @version            1.0
116  */
117 WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
118                              void *pvRecvBuffer, u32 u32RecvBufferSize,
119                              u32 *pu32ReceivedLength)
120 {
121
122         Message *pstrMessage;
123         WILC_ErrNo s32RetStatus = WILC_SUCCESS;
124         unsigned long flags;
125         if ((pHandle == NULL) || (u32RecvBufferSize == 0)
126             || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) {
127                 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
128         }
129
130         if (pHandle->bExiting == true) {
131                 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
132         }
133
134         spin_lock_irqsave(&pHandle->strCriticalSection, flags);
135         pHandle->u32ReceiversCount++;
136         spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
137
138         down(&(pHandle->hSem));
139
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);
145         } else {
146                 /* other non-timeout scenarios */
147                 WILC_ERRORCHECK(s32RetStatus);
148
149                 if (pHandle->bExiting) {
150                         WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
151                 }
152
153                 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
154
155                 pstrMessage = pHandle->pstrMessageList;
156                 if (pstrMessage == NULL) {
157                         spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
158                         WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
159                 }
160                 /* check buffer size */
161                 if (u32RecvBufferSize < pstrMessage->u32Length) {
162                         spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
163                         up(&pHandle->hSem);
164                         WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW);
165                 }
166
167                 /* consume the message */
168                 pHandle->u32ReceiversCount--;
169                 memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
170                 *pu32ReceivedLength = pstrMessage->u32Length;
171
172                 pHandle->pstrMessageList = pstrMessage->pstrNext;
173
174                 kfree(pstrMessage->pvBuffer);
175                 kfree(pstrMessage);
176
177                 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
178
179         }
180
181         WILC_CATCH(s32RetStatus)
182         {
183         }
184
185         return s32RetStatus;
186 }