GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / shared / linux_rpc_osl.c
blob429cd6e81fece12b4e4bf536eda1554b4f5c9066
1 /*
2 * RPC OSL linux port
3 * Broadcom 802.11abg Networking Device Driver
5 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * $Id: linux_rpc_osl.c 300516 2011-12-04 17:39:44Z $
21 #if (!defined(WLC_HIGH) && !defined(WLC_LOW))
22 #error "SPLIT"
23 #endif
25 #ifdef BCMDRIVER
26 #include <typedefs.h>
27 #include <bcmdefs.h>
28 #include <bcmendian.h>
29 #include <osl.h>
30 #include <bcmutils.h>
32 #include <rpc_osl.h>
33 #include <linuxver.h>
35 struct rpc_osl {
36 osl_t *osh;
37 wait_queue_head_t wait; /* To block awaiting init frame */
38 spinlock_t lock;
39 bool wakeup;
40 ulong flags;
43 rpc_osl_t *
44 rpc_osl_attach(osl_t *osh)
46 rpc_osl_t *rpc_osh;
48 if ((rpc_osh = (rpc_osl_t *)MALLOC(osh, sizeof(rpc_osl_t))) == NULL)
49 return NULL;
51 spin_lock_init(&rpc_osh->lock);
52 init_waitqueue_head(&rpc_osh->wait);
53 /* set the wakeup flag to TRUE, so we are ready
54 to detect a call return even before we call rpc_osl_wait.
56 rpc_osh->wakeup = TRUE;
57 rpc_osh->osh = osh;
59 return rpc_osh;
62 void
63 rpc_osl_detach(rpc_osl_t *rpc_osh)
65 if (!rpc_osh)
66 return;
68 MFREE(rpc_osh->osh, rpc_osh, sizeof(rpc_osl_t));
71 int
72 rpc_osl_wait(rpc_osl_t *rpc_osh, uint ms, bool *ptimedout)
74 unsigned long j;
75 int ret;
77 /* printf("%s timeout:%d\n", __FUNCTION__, ms); */
78 j = ms * HZ / 1000;
80 /* yield the control back to OS, wait for wake_up() call up to j ms */
81 ret = wait_event_interruptible_timeout(rpc_osh->wait, rpc_osh->wakeup == FALSE, j);
83 /* 0 ret => timeout */
84 if (ret == 0) {
85 if (ptimedout)
86 *ptimedout = TRUE;
87 } else if (ret < 0)
88 return ret;
90 RPC_OSL_LOCK(rpc_osh);
91 /* set the flag to be ready for next return */
92 rpc_osh->wakeup = TRUE;
93 RPC_OSL_UNLOCK(rpc_osh);
95 return 0;
98 void
99 rpc_osl_wake(rpc_osl_t *rpc_osh)
101 /* Wake up if someone's waiting */
102 if (rpc_osh->wakeup == TRUE) {
103 /* this is the only place where this flag is set to FALSE
104 It will be reset to TRUE in rpc_osl_wait.
106 rpc_osh->wakeup = FALSE;
107 wake_up(&rpc_osh->wait);
111 void
112 rpc_osl_lock(rpc_osl_t *rpc_osh)
114 spin_lock_irqsave(&rpc_osh->lock, rpc_osh->flags);
117 void
118 rpc_osl_unlock(rpc_osl_t *rpc_osh)
120 spin_unlock_irqrestore(&rpc_osh->lock, rpc_osh->flags);
123 #else /* !BCMDRIVER */
125 #include <typedefs.h>
126 #include <osl.h>
127 #include <rpc_osl.h>
128 #include <pthread.h>
129 #include <time.h>
130 #include <errno.h>
132 struct rpc_osl {
133 osl_t *osh;
134 pthread_cond_t wait; /* To block awaiting init frame */
135 pthread_mutex_t lock;
136 bool wakeup;
139 rpc_osl_t *
140 rpc_osl_attach(osl_t *osh)
142 rpc_osl_t *rpc_osh;
144 if ((rpc_osh = (rpc_osl_t *)MALLOC(osh, sizeof(rpc_osl_t))) == NULL)
145 return NULL;
147 rpc_osh->osh = osh;
148 pthread_mutex_init(&rpc_osh->lock, NULL);
149 pthread_cond_init(&rpc_osh->wait, NULL);
150 rpc_osh->wakeup = FALSE;
152 return rpc_osh;
155 void
156 rpc_osl_detach(rpc_osl_t *rpc_osh)
158 if (rpc_osh) {
159 MFREE(rpc_osh->osh, rpc_osh, sizeof(rpc_osl_t));
164 rpc_osl_wait(rpc_osl_t *rpc_osh, uint ms, bool *ptimedout)
166 struct timespec timeout;
167 int ret;
169 printf("%s timeout:%d\n", __FUNCTION__, ms);
170 clock_gettime(CLOCK_REALTIME, &timeout);
171 timeout.tv_sec += ms/1000;
172 ms = ms - ((ms/1000) * 1000);
173 timeout.tv_nsec += ms * 1000 * 1000;
175 RPC_OSL_LOCK(rpc_osh);
176 rpc_osh->wakeup = FALSE;
177 while (rpc_osh->wakeup == FALSE) {
178 ret = pthread_cond_timedwait(&rpc_osh->wait, &rpc_osh->lock, &timeout);
179 /* check for timedout instead of wait condition */
180 if (ret == ETIMEDOUT) {
181 if (ptimedout)
182 *ptimedout = TRUE;
183 rpc_osh->wakeup = TRUE;
184 } else if (ret)
185 break; /* some other error (e.g. interrupt) */
187 RPC_OSL_UNLOCK(rpc_osh);
189 return ret;
191 void
192 rpc_osl_wake(rpc_osl_t *rpc_osh)
194 rpc_osh->wakeup = TRUE;
195 pthread_cond_signal(&rpc_osh->wait);
198 void
199 rpc_osl_lock(rpc_osl_t *rpc_osh)
201 pthread_mutex_lock(&rpc_osh->lock);
204 void
205 rpc_osl_unlock(rpc_osl_t *rpc_osh)
207 pthread_mutex_unlock(&rpc_osh->lock);
210 #endif /* BCMDRIVER */