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