blob: 70e4fa6a07a65969af35529745d5c38d56399c81 [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001
Dean Leec3ea8a72015-06-16 15:28:21 +09002#include "wilc_msgqueue.h"
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003#include <linux/spinlock.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004
5/*!
6 * @author syounan
7 * @date 1 Sep 2010
8 * @note copied from FLO glue implementatuion
9 * @version 1.0
10 */
Greg Kroah-Hartmanc4f83a52015-08-17 11:32:38 -070011WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle)
Johnny Kimc5c77ba2015-05-11 14:30:56 +090012{
Johnny Kimc5c77ba2015-05-11 14:30:56 +090013 spin_lock_init(&pHandle->strCriticalSection);
Arnd Bergmann83383ea2015-06-01 21:06:43 +020014 sema_init(&pHandle->hSem, 0);
15 pHandle->pstrMessageList = NULL;
16 pHandle->u32ReceiversCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +090017 pHandle->bExiting = false;
Arnd Bergmann83383ea2015-06-01 21:06:43 +020018 return WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090019}
20
21/*!
22 * @author syounan
23 * @date 1 Sep 2010
24 * @note copied from FLO glue implementatuion
25 * @version 1.0
26 */
Greg Kroah-Hartmanc4f83a52015-08-17 11:32:38 -070027WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle)
Johnny Kimc5c77ba2015-05-11 14:30:56 +090028{
29
Dean Lee72ed4dc2015-06-12 14:11:44 +090030 pHandle->bExiting = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090031
32 /* Release any waiting receiver thread. */
33 while (pHandle->u32ReceiversCount > 0) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +020034 up(&(pHandle->hSem));
Johnny Kimc5c77ba2015-05-11 14:30:56 +090035 pHandle->u32ReceiversCount--;
36 }
37
Johnny Kimc5c77ba2015-05-11 14:30:56 +090038 while (pHandle->pstrMessageList != NULL) {
39 Message *pstrMessge = pHandle->pstrMessageList->pstrNext;
Chaehyun Lim49188af2015-08-11 10:32:41 +090040 kfree(pHandle->pstrMessageList);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090041 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 */
53WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle,
Greg Kroah-Hartmanc4f83a52015-08-17 11:32:38 -070054 const void *pvSendBuffer, u32 u32SendBufferSize)
Johnny Kimc5c77ba2015-05-11 14:30:56 +090055{
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
Dean Lee72ed4dc2015-06-12 14:11:44 +090064 if (pHandle->bExiting == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +090065 WILC_ERRORREPORT(s32RetStatus, WILC_FAIL);
66 }
67
68 spin_lock_irqsave(&pHandle->strCriticalSection, flags);
69
70 /* construct a new message */
Chaehyun Lim5c078282015-08-17 11:05:10 +090071 pstrMessage = kmalloc(sizeof(Message), GFP_ATOMIC);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090072 WILC_NULLCHECK(s32RetStatus, pstrMessage);
73 pstrMessage->u32Length = u32SendBufferSize;
74 pstrMessage->pstrNext = NULL;
75 pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize);
76 WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +090077 memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090078
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
Arnd Bergmann83383ea2015-06-01 21:06:43 +020093 up(&pHandle->hSem);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090094
95 WILC_CATCH(s32RetStatus)
96 {
97 /* error occured, free any allocations */
98 if (pstrMessage != NULL) {
99 if (pstrMessage->pvBuffer != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900100 kfree(pstrMessage->pvBuffer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900101 }
Chaehyun Lim49188af2015-08-11 10:32:41 +0900102 kfree(pstrMessage);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900103 }
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 */
117WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle,
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900118 void *pvRecvBuffer, u32 u32RecvBufferSize,
Greg Kroah-Hartmanc4f83a52015-08-17 11:32:38 -0700119 u32 *pu32ReceivedLength)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900120{
121
122 Message *pstrMessage;
123 WILC_ErrNo s32RetStatus = WILC_SUCCESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900124 unsigned long flags;
125 if ((pHandle == NULL) || (u32RecvBufferSize == 0)
126 || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) {
127 WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT);
128 }
129
Dean Lee72ed4dc2015-06-12 14:11:44 +0900130 if (pHandle->bExiting == true) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900131 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
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200138 down(&(pHandle->hSem));
139
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900140 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);
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200163 up(&pHandle->hSem);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900164 WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW);
165 }
166
167 /* consume the message */
168 pHandle->u32ReceiversCount--;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900169 memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900170 *pu32ReceivedLength = pstrMessage->u32Length;
171
172 pHandle->pstrMessageList = pstrMessage->pstrNext;
173
Chaehyun Lim49188af2015-08-11 10:32:41 +0900174 kfree(pstrMessage->pvBuffer);
175 kfree(pstrMessage);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900176
177 spin_unlock_irqrestore(&pHandle->strCriticalSection, flags);
178
179 }
180
181 WILC_CATCH(s32RetStatus)
182 {
183 }
184
185 return s32RetStatus;
186}