3 * Broadcom 802.11abg Networking Device Driver
5 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
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))
28 #include <bcmendian.h>
37 wait_queue_head_t wait
; /* To block awaiting init frame */
44 rpc_osl_attach(osl_t
*osh
)
48 if ((rpc_osh
= (rpc_osl_t
*)MALLOC(osh
, sizeof(rpc_osl_t
))) == 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
;
63 rpc_osl_detach(rpc_osl_t
*rpc_osh
)
68 MFREE(rpc_osh
->osh
, rpc_osh
, sizeof(rpc_osl_t
));
72 rpc_osl_wait(rpc_osl_t
*rpc_osh
, uint ms
, bool *ptimedout
)
77 /* printf("%s timeout:%d\n", __FUNCTION__, ms); */
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 */
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
);
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
);
112 rpc_osl_lock(rpc_osl_t
*rpc_osh
)
114 spin_lock_irqsave(&rpc_osh
->lock
, rpc_osh
->flags
);
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>
134 pthread_cond_t wait
; /* To block awaiting init frame */
135 pthread_mutex_t lock
;
140 rpc_osl_attach(osl_t
*osh
)
144 if ((rpc_osh
= (rpc_osl_t
*)MALLOC(osh
, sizeof(rpc_osl_t
))) == NULL
)
148 pthread_mutex_init(&rpc_osh
->lock
, NULL
);
149 pthread_cond_init(&rpc_osh
->wait
, NULL
);
150 rpc_osh
->wakeup
= FALSE
;
156 rpc_osl_detach(rpc_osl_t
*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
;
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
) {
183 rpc_osh
->wakeup
= TRUE
;
185 break; /* some other error (e.g. interrupt) */
187 RPC_OSL_UNLOCK(rpc_osh
);
192 rpc_osl_wake(rpc_osl_t
*rpc_osh
)
194 rpc_osh
->wakeup
= TRUE
;
195 pthread_cond_signal(&rpc_osh
->wait
);
199 rpc_osl_lock(rpc_osl_t
*rpc_osh
)
201 pthread_mutex_lock(&rpc_osh
->lock
);
205 rpc_osl_unlock(rpc_osl_t
*rpc_osh
)
207 pthread_mutex_unlock(&rpc_osh
->lock
);
210 #endif /* BCMDRIVER */