staging: wilc1000: rename pu32ReceivedLength in wilc_mq_recv
[deliverable/linux.git] / drivers / staging / wilc1000 / wilc_msgqueue.c
CommitLineData
c5c77ba1 1
c3ea8a72 2#include "wilc_msgqueue.h"
c5c77ba1 3#include <linux/spinlock.h>
6569738a 4#include "linux_wlan_common.h"
7ae43363 5#include <linux/errno.h>
94723907 6#include <linux/slab.h>
c5c77ba1
JK
7
8/*!
9 * @author syounan
10 * @date 1 Sep 2010
11 * @note copied from FLO glue implementatuion
12 * @version 1.0
13 */
2cc08b4f 14int wilc_mq_create(struct message_queue *mq)
c5c77ba1 15{
2cc08b4f
CL
16 spin_lock_init(&mq->lock);
17 sema_init(&mq->sem, 0);
18 mq->msg_list = NULL;
19 mq->recv_count = 0;
20 mq->exiting = false;
e6e12661 21 return 0;
c5c77ba1
JK
22}
23
24/*!
25 * @author syounan
26 * @date 1 Sep 2010
27 * @note copied from FLO glue implementatuion
28 * @version 1.0
29 */
d742f67e 30int wilc_mq_destroy(struct message_queue *mq)
c5c77ba1 31{
d742f67e 32 mq->exiting = true;
c5c77ba1
JK
33
34 /* Release any waiting receiver thread. */
d742f67e
CL
35 while (mq->recv_count > 0) {
36 up(&mq->sem);
37 mq->recv_count--;
c5c77ba1
JK
38 }
39
d742f67e 40 while (mq->msg_list) {
fca978b7 41 struct message *msg = mq->msg_list->next;
8dfaafd6 42
d742f67e 43 kfree(mq->msg_list);
fca978b7 44 mq->msg_list = msg;
c5c77ba1
JK
45 }
46
e6e12661 47 return 0;
c5c77ba1
JK
48}
49
50/*!
51 * @author syounan
52 * @date 1 Sep 2010
53 * @note copied from FLO glue implementatuion
54 * @version 1.0
55 */
5eb35975 56int wilc_mq_send(struct message_queue *mq,
81e886e0 57 const void *send_buf, u32 send_buf_size)
c5c77ba1 58{
c5c77ba1 59 unsigned long flags;
669fd507 60 struct message *new_msg = NULL;
c5c77ba1 61
81e886e0 62 if ((!mq) || (send_buf_size == 0) || (!send_buf)) {
832f4fa5 63 PRINT_ER("mq or send_buf is null\n");
dee1bf76 64 return -EINVAL;
c5c77ba1
JK
65 }
66
5eb35975
CL
67 if (mq->exiting) {
68 PRINT_ER("mq fail\n");
dbef61e7 69 return -EFAULT;
c5c77ba1
JK
70 }
71
c5c77ba1 72 /* construct a new message */
669fd507
CL
73 new_msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
74 if (!new_msg)
7ae43363 75 return -ENOMEM;
dbef61e7 76
669fd507
CL
77 new_msg->len = send_buf_size;
78 new_msg->next = NULL;
79 new_msg->buf = kmemdup(send_buf, send_buf_size, GFP_ATOMIC);
80 if (!new_msg->buf) {
81 kfree(new_msg);
dbef61e7 82 return -ENOMEM;
7ae43363 83 }
c5c77ba1 84
5eb35975 85 spin_lock_irqsave(&mq->lock, flags);
dbef61e7 86
c5c77ba1 87 /* add it to the message queue */
5eb35975 88 if (!mq->msg_list) {
669fd507 89 mq->msg_list = new_msg;
c5c77ba1 90 } else {
bd07b007 91 struct message *tail_msg = mq->msg_list;
8dfaafd6 92
bd07b007
CL
93 while (tail_msg->next)
94 tail_msg = tail_msg->next;
6fffc621 95
bd07b007 96 tail_msg->next = new_msg;
c5c77ba1
JK
97 }
98
5eb35975 99 spin_unlock_irqrestore(&mq->lock, flags);
c5c77ba1 100
5eb35975 101 up(&mq->sem);
c5c77ba1 102
dbef61e7 103 return 0;
c5c77ba1
JK
104}
105
c5c77ba1
JK
106/*!
107 * @author syounan
108 * @date 1 Sep 2010
109 * @note copied from FLO glue implementatuion
110 * @version 1.0
111 */
24752783 112int wilc_mq_recv(struct message_queue *mq,
62082cbe 113 void *recv_buf, u32 recv_buf_size, u32 *recv_len)
c5c77ba1 114{
d16791bf 115 struct message *pstrMessage;
c5c77ba1 116 unsigned long flags;
8dfaafd6 117
e8f2d1f1 118 if ((!mq) || (recv_buf_size == 0)
62082cbe 119 || (!recv_buf) || (!recv_len)) {
f034b01e 120 PRINT_ER("mq or recv_buf is null\n");
24db713f 121 return -EINVAL;
c5c77ba1
JK
122 }
123
24752783
CL
124 if (mq->exiting) {
125 PRINT_ER("mq fail\n");
24db713f 126 return -EFAULT;
c5c77ba1
JK
127 }
128
24752783
CL
129 spin_lock_irqsave(&mq->lock, flags);
130 mq->recv_count++;
131 spin_unlock_irqrestore(&mq->lock, flags);
c5c77ba1 132
24752783
CL
133 down(&mq->sem);
134 spin_lock_irqsave(&mq->lock, flags);
c5c77ba1 135
24752783 136 pstrMessage = mq->msg_list;
24db713f 137 if (!pstrMessage) {
24752783 138 spin_unlock_irqrestore(&mq->lock, flags);
24db713f
LK
139 PRINT_ER("pstrMessage is null\n");
140 return -EFAULT;
c5c77ba1 141 }
24db713f 142 /* check buffer size */
e8f2d1f1 143 if (recv_buf_size < pstrMessage->len) {
24752783
CL
144 spin_unlock_irqrestore(&mq->lock, flags);
145 up(&mq->sem);
e8f2d1f1 146 PRINT_ER("recv_buf_size overflow\n");
24db713f 147 return -EOVERFLOW;
c5c77ba1
JK
148 }
149
24db713f 150 /* consume the message */
24752783 151 mq->recv_count--;
f034b01e 152 memcpy(recv_buf, pstrMessage->buf, pstrMessage->len);
62082cbe 153 *recv_len = pstrMessage->len;
24db713f 154
24752783 155 mq->msg_list = pstrMessage->next;
24db713f 156
78d50f94 157 kfree(pstrMessage->buf);
24db713f
LK
158 kfree(pstrMessage);
159
24752783 160 spin_unlock_irqrestore(&mq->lock, flags);
24db713f 161
ff5d40a4 162 return 0;
c5c77ba1 163}
This page took 0.154782 seconds and 5 git commands to generate.