xref: /wlan-driver/qcacld-3.0/components/dsc/src/__wlan_dsc.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #include "qdf_list.h"
21*5113495bSYour Name #include "qdf_mem.h"
22*5113495bSYour Name #include "qdf_status.h"
23*5113495bSYour Name #include "qdf_str.h"
24*5113495bSYour Name #include "qdf_threads.h"
25*5113495bSYour Name #include "qdf_timer.h"
26*5113495bSYour Name #include "__wlan_dsc.h"
27*5113495bSYour Name #include "cds_api.h"
28*5113495bSYour Name 
29*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
__dsc_dbg_op_timeout(void * opaque_op)30*5113495bSYour Name static void __dsc_dbg_op_timeout(void *opaque_op)
31*5113495bSYour Name {
32*5113495bSYour Name 	struct dsc_op *op = opaque_op;
33*5113495bSYour Name 
34*5113495bSYour Name 	qdf_print_thread_trace(op->thread);
35*5113495bSYour Name 	QDF_DEBUG_PANIC("Operation '%s' exceeded %ums",
36*5113495bSYour Name 			op->func, DSC_OP_TIMEOUT_MS);
37*5113495bSYour Name }
38*5113495bSYour Name 
39*5113495bSYour Name /**
40*5113495bSYour Name  * __dsc_dbg_ops_init() - initialize debug ops data structures
41*5113495bSYour Name  * @ops: the ops container to initialize
42*5113495bSYour Name  *
43*5113495bSYour Name  * Return: None
44*5113495bSYour Name  */
__dsc_dbg_ops_init(struct dsc_ops * ops)45*5113495bSYour Name static inline void __dsc_dbg_ops_init(struct dsc_ops *ops)
46*5113495bSYour Name {
47*5113495bSYour Name 	qdf_list_create(&ops->list, 0);
48*5113495bSYour Name }
49*5113495bSYour Name 
50*5113495bSYour Name /**
51*5113495bSYour Name  * __dsc_dbg_ops_deinit() - de-initialize debug ops data structures
52*5113495bSYour Name  * @ops: the ops container to de-initialize
53*5113495bSYour Name  *
54*5113495bSYour Name  * Return: None
55*5113495bSYour Name  */
__dsc_dbg_ops_deinit(struct dsc_ops * ops)56*5113495bSYour Name static inline void __dsc_dbg_ops_deinit(struct dsc_ops *ops)
57*5113495bSYour Name {
58*5113495bSYour Name 	qdf_list_destroy(&ops->list);
59*5113495bSYour Name }
60*5113495bSYour Name 
61*5113495bSYour Name /**
62*5113495bSYour Name  * __dsc_dbg_ops_insert() - insert @func into the debug information in @ops
63*5113495bSYour Name  * @ops: the ops container to insert into
64*5113495bSYour Name  * @func: the debug information to insert
65*5113495bSYour Name  *
66*5113495bSYour Name  * Return: QDF_STATUS
67*5113495bSYour Name  */
__dsc_dbg_ops_insert(struct dsc_ops * ops,const char * func)68*5113495bSYour Name static QDF_STATUS __dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func)
69*5113495bSYour Name {
70*5113495bSYour Name 	QDF_STATUS status;
71*5113495bSYour Name 	struct dsc_op *op;
72*5113495bSYour Name 
73*5113495bSYour Name 	op = qdf_mem_malloc(sizeof(*op));
74*5113495bSYour Name 	if (!op)
75*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
76*5113495bSYour Name 
77*5113495bSYour Name 	op->thread = qdf_get_current_task();
78*5113495bSYour Name 	status = qdf_timer_init(NULL, &op->timeout_timer, __dsc_dbg_op_timeout,
79*5113495bSYour Name 				op, QDF_TIMER_TYPE_SW);
80*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
81*5113495bSYour Name 		goto free_op;
82*5113495bSYour Name 
83*5113495bSYour Name 	op->func = func;
84*5113495bSYour Name 
85*5113495bSYour Name 	qdf_timer_start(&op->timeout_timer, DSC_OP_TIMEOUT_MS);
86*5113495bSYour Name 	qdf_list_insert_back(&ops->list, &op->node);
87*5113495bSYour Name 
88*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
89*5113495bSYour Name 
90*5113495bSYour Name free_op:
91*5113495bSYour Name 	qdf_mem_free(op);
92*5113495bSYour Name 
93*5113495bSYour Name 	return status;
94*5113495bSYour Name }
95*5113495bSYour Name 
96*5113495bSYour Name /**
97*5113495bSYour Name  * __dsc_dbg_ops_remove() - remove @func from the debug information in @ops
98*5113495bSYour Name  * @ops: the ops container to remove from
99*5113495bSYour Name  * @func: the debug information to remove
100*5113495bSYour Name  *
101*5113495bSYour Name  * Return: None
102*5113495bSYour Name  */
__dsc_dbg_ops_remove(struct dsc_ops * ops,const char * func)103*5113495bSYour Name static void __dsc_dbg_ops_remove(struct dsc_ops *ops, const char *func)
104*5113495bSYour Name {
105*5113495bSYour Name 	struct dsc_op *op;
106*5113495bSYour Name 
107*5113495bSYour Name 	/* Global pending op depth is usually <=3. Use linear search for now */
108*5113495bSYour Name 	qdf_list_for_each(&ops->list, op, node) {
109*5113495bSYour Name 		if (!qdf_str_eq(op->func, func))
110*5113495bSYour Name 			continue;
111*5113495bSYour Name 
112*5113495bSYour Name 		/* this is safe because we cease iteration */
113*5113495bSYour Name 		qdf_list_remove_node(&ops->list, &op->node);
114*5113495bSYour Name 
115*5113495bSYour Name 		qdf_timer_stop(&op->timeout_timer);
116*5113495bSYour Name 		qdf_timer_free(&op->timeout_timer);
117*5113495bSYour Name 		qdf_mem_free(op);
118*5113495bSYour Name 
119*5113495bSYour Name 		return;
120*5113495bSYour Name 	}
121*5113495bSYour Name 
122*5113495bSYour Name 	QDF_DEBUG_PANIC("Driver op '%s' is not pending", func);
123*5113495bSYour Name }
124*5113495bSYour Name #else
__dsc_dbg_ops_init(struct dsc_ops * ops)125*5113495bSYour Name static inline void __dsc_dbg_ops_init(struct dsc_ops *ops) { }
126*5113495bSYour Name 
__dsc_dbg_ops_deinit(struct dsc_ops * ops)127*5113495bSYour Name static inline void __dsc_dbg_ops_deinit(struct dsc_ops *ops) { }
128*5113495bSYour Name 
129*5113495bSYour Name static inline QDF_STATUS
__dsc_dbg_ops_insert(struct dsc_ops * ops,const char * func)130*5113495bSYour Name __dsc_dbg_ops_insert(struct dsc_ops *ops, const char *func)
131*5113495bSYour Name {
132*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
133*5113495bSYour Name }
134*5113495bSYour Name 
135*5113495bSYour Name static inline void
__dsc_dbg_ops_remove(struct dsc_ops * ops,const char * func)136*5113495bSYour Name __dsc_dbg_ops_remove(struct dsc_ops *ops, const char *func) { }
137*5113495bSYour Name #endif /* WLAN_DSC_DEBUG */
138*5113495bSYour Name 
__dsc_ops_init(struct dsc_ops * ops)139*5113495bSYour Name void __dsc_ops_init(struct dsc_ops *ops)
140*5113495bSYour Name {
141*5113495bSYour Name 	ops->count = 0;
142*5113495bSYour Name 	qdf_event_create(&ops->event);
143*5113495bSYour Name 	__dsc_dbg_ops_init(ops);
144*5113495bSYour Name }
145*5113495bSYour Name 
__dsc_ops_deinit(struct dsc_ops * ops)146*5113495bSYour Name void __dsc_ops_deinit(struct dsc_ops *ops)
147*5113495bSYour Name {
148*5113495bSYour Name 	/* assert no ops in flight */
149*5113495bSYour Name 	dsc_assert(!ops->count);
150*5113495bSYour Name 
151*5113495bSYour Name 	__dsc_dbg_ops_deinit(ops);
152*5113495bSYour Name 	qdf_event_destroy(&ops->event);
153*5113495bSYour Name }
154*5113495bSYour Name 
__dsc_ops_insert(struct dsc_ops * ops,const char * func)155*5113495bSYour Name QDF_STATUS __dsc_ops_insert(struct dsc_ops *ops, const char *func)
156*5113495bSYour Name {
157*5113495bSYour Name 	QDF_STATUS status;
158*5113495bSYour Name 
159*5113495bSYour Name 	status = __dsc_dbg_ops_insert(ops, func);
160*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
161*5113495bSYour Name 		return status;
162*5113495bSYour Name 
163*5113495bSYour Name 	ops->count++;
164*5113495bSYour Name 
165*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
166*5113495bSYour Name }
167*5113495bSYour Name 
__dsc_ops_remove(struct dsc_ops * ops,const char * func)168*5113495bSYour Name bool __dsc_ops_remove(struct dsc_ops *ops, const char *func)
169*5113495bSYour Name {
170*5113495bSYour Name 	dsc_assert(ops->count);
171*5113495bSYour Name 	ops->count--;
172*5113495bSYour Name 
173*5113495bSYour Name 	__dsc_dbg_ops_remove(ops, func);
174*5113495bSYour Name 
175*5113495bSYour Name 	return ops->count == 0;
176*5113495bSYour Name }
177*5113495bSYour Name 
178*5113495bSYour Name #ifdef WLAN_DSC_DEBUG
__dsc_dbg_trans_timeout(void * opaque_trans)179*5113495bSYour Name static void __dsc_dbg_trans_timeout(void *opaque_trans)
180*5113495bSYour Name {
181*5113495bSYour Name 	struct dsc_trans *trans = opaque_trans;
182*5113495bSYour Name 
183*5113495bSYour Name 	qdf_print_thread_trace(trans->thread);
184*5113495bSYour Name 
185*5113495bSYour Name 	if (cds_is_fw_down() &&
186*5113495bSYour Name 	    !qdf_str_eq(trans->active_desc, "hdd_soc_recovery_shutdown"))
187*5113495bSYour Name 		dsc_err("fw is down avoid panic");
188*5113495bSYour Name 	else
189*5113495bSYour Name 		QDF_DEBUG_PANIC("Transition '%s' exceeded %ums",
190*5113495bSYour Name 				trans->active_desc, DSC_TRANS_TIMEOUT_MS);
191*5113495bSYour Name }
192*5113495bSYour Name 
193*5113495bSYour Name /**
194*5113495bSYour Name  * __dsc_dbg_trans_timeout_start() - start a timeout timer for @trans
195*5113495bSYour Name  * @trans: the active transition to start a timeout timer for
196*5113495bSYour Name  *
197*5113495bSYour Name  * Return: QDF_STATUS
198*5113495bSYour Name  */
__dsc_dbg_trans_timeout_start(struct dsc_trans * trans)199*5113495bSYour Name static QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans)
200*5113495bSYour Name {
201*5113495bSYour Name 	QDF_STATUS status;
202*5113495bSYour Name 
203*5113495bSYour Name 	trans->thread = qdf_get_current_task();
204*5113495bSYour Name 	status = qdf_timer_init(NULL, &trans->timeout_timer,
205*5113495bSYour Name 				__dsc_dbg_trans_timeout, trans,
206*5113495bSYour Name 				QDF_TIMER_TYPE_SW);
207*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
208*5113495bSYour Name 		return status;
209*5113495bSYour Name 
210*5113495bSYour Name 	qdf_timer_start(&trans->timeout_timer, DSC_TRANS_TIMEOUT_MS);
211*5113495bSYour Name 
212*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
213*5113495bSYour Name }
214*5113495bSYour Name 
215*5113495bSYour Name /**
216*5113495bSYour Name  * __dsc_dbg_trans_timeout_stop() - stop the timeout timer for @trans
217*5113495bSYour Name  * @trans: the active transition to stop the timeout timer for
218*5113495bSYour Name  *
219*5113495bSYour Name  * Return: None
220*5113495bSYour Name  */
__dsc_dbg_trans_timeout_stop(struct dsc_trans * trans)221*5113495bSYour Name static void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans)
222*5113495bSYour Name {
223*5113495bSYour Name 	qdf_timer_stop(&trans->timeout_timer);
224*5113495bSYour Name 	qdf_timer_free(&trans->timeout_timer);
225*5113495bSYour Name }
226*5113495bSYour Name 
__dsc_dbg_tran_wait_timeout(void * opaque_tran)227*5113495bSYour Name static void __dsc_dbg_tran_wait_timeout(void *opaque_tran)
228*5113495bSYour Name {
229*5113495bSYour Name 	struct dsc_tran *tran = opaque_tran;
230*5113495bSYour Name 
231*5113495bSYour Name 	qdf_print_thread_trace(tran->thread);
232*5113495bSYour Name 	QDF_DEBUG_PANIC("Transition '%s' waited more than %ums",
233*5113495bSYour Name 			tran->desc, DSC_TRANS_WAIT_TIMEOUT_MS);
234*5113495bSYour Name }
235*5113495bSYour Name 
236*5113495bSYour Name /**
237*5113495bSYour Name  * __dsc_dbg_tran_wait_timeout_start() - start a timeout timer for @tran
238*5113495bSYour Name  * @tran: the pending transition to start a timeout timer for
239*5113495bSYour Name  *
240*5113495bSYour Name  * Return: QDF_STATUS
241*5113495bSYour Name  */
__dsc_dbg_tran_wait_timeout_start(struct dsc_tran * tran)242*5113495bSYour Name static QDF_STATUS __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran)
243*5113495bSYour Name {
244*5113495bSYour Name 	QDF_STATUS status;
245*5113495bSYour Name 
246*5113495bSYour Name 	tran->thread = qdf_get_current_task();
247*5113495bSYour Name 	status = qdf_timer_init(NULL, &tran->timeout_timer,
248*5113495bSYour Name 				__dsc_dbg_tran_wait_timeout, tran,
249*5113495bSYour Name 				QDF_TIMER_TYPE_SW);
250*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
251*5113495bSYour Name 		return status;
252*5113495bSYour Name 
253*5113495bSYour Name 	qdf_timer_start(&tran->timeout_timer, DSC_TRANS_WAIT_TIMEOUT_MS);
254*5113495bSYour Name 
255*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
256*5113495bSYour Name }
257*5113495bSYour Name 
258*5113495bSYour Name /**
259*5113495bSYour Name  * __dsc_dbg_tran_wait_timeout_stop() - stop the timeout timer for @tran
260*5113495bSYour Name  * @tran: the pending transition to stop the timeout timer for
261*5113495bSYour Name  *
262*5113495bSYour Name  * Return: None
263*5113495bSYour Name  */
__dsc_dbg_tran_wait_timeout_stop(struct dsc_tran * tran)264*5113495bSYour Name static void __dsc_dbg_tran_wait_timeout_stop(struct dsc_tran *tran)
265*5113495bSYour Name {
266*5113495bSYour Name 	qdf_timer_stop(&tran->timeout_timer);
267*5113495bSYour Name 	qdf_timer_free(&tran->timeout_timer);
268*5113495bSYour Name }
269*5113495bSYour Name #else
__dsc_dbg_trans_timeout_start(struct dsc_trans * trans)270*5113495bSYour Name static inline QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans)
271*5113495bSYour Name {
272*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
273*5113495bSYour Name }
274*5113495bSYour Name 
__dsc_dbg_trans_timeout_stop(struct dsc_trans * trans)275*5113495bSYour Name static inline void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans) { }
276*5113495bSYour Name 
277*5113495bSYour Name static inline QDF_STATUS
__dsc_dbg_tran_wait_timeout_start(struct dsc_tran * tran)278*5113495bSYour Name __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran)
279*5113495bSYour Name {
280*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
281*5113495bSYour Name }
282*5113495bSYour Name 
__dsc_dbg_tran_wait_timeout_stop(struct dsc_tran * tran)283*5113495bSYour Name static inline void __dsc_dbg_tran_wait_timeout_stop(struct dsc_tran *tran) { }
284*5113495bSYour Name #endif /* WLAN_DSC_DEBUG */
285*5113495bSYour Name 
__dsc_trans_init(struct dsc_trans * trans)286*5113495bSYour Name void __dsc_trans_init(struct dsc_trans *trans)
287*5113495bSYour Name {
288*5113495bSYour Name 	trans->active_desc = NULL;
289*5113495bSYour Name 	qdf_list_create(&trans->queue, 0);
290*5113495bSYour Name }
291*5113495bSYour Name 
__dsc_trans_deinit(struct dsc_trans * trans)292*5113495bSYour Name void __dsc_trans_deinit(struct dsc_trans *trans)
293*5113495bSYour Name {
294*5113495bSYour Name 	qdf_list_destroy(&trans->queue);
295*5113495bSYour Name 	trans->active_desc = NULL;
296*5113495bSYour Name }
297*5113495bSYour Name 
__dsc_trans_start(struct dsc_trans * trans,const char * desc)298*5113495bSYour Name QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc)
299*5113495bSYour Name {
300*5113495bSYour Name 	QDF_STATUS status;
301*5113495bSYour Name 
302*5113495bSYour Name 	status = __dsc_dbg_trans_timeout_start(trans);
303*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
304*5113495bSYour Name 		return status;
305*5113495bSYour Name 
306*5113495bSYour Name 	dsc_assert(!trans->active_desc);
307*5113495bSYour Name 	trans->active_desc = desc;
308*5113495bSYour Name 
309*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
310*5113495bSYour Name }
311*5113495bSYour Name 
__dsc_trans_stop(struct dsc_trans * trans)312*5113495bSYour Name void __dsc_trans_stop(struct dsc_trans *trans)
313*5113495bSYour Name {
314*5113495bSYour Name 	dsc_assert(trans->active_desc);
315*5113495bSYour Name 	trans->active_desc = NULL;
316*5113495bSYour Name 	__dsc_dbg_trans_timeout_stop(trans);
317*5113495bSYour Name }
318*5113495bSYour Name 
__dsc_trans_queue(struct dsc_trans * trans,struct dsc_tran * tran,const char * desc)319*5113495bSYour Name QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran,
320*5113495bSYour Name 			     const char *desc)
321*5113495bSYour Name {
322*5113495bSYour Name 	QDF_STATUS status;
323*5113495bSYour Name 
324*5113495bSYour Name 	tran->abort = false;
325*5113495bSYour Name 	tran->desc = desc;
326*5113495bSYour Name 	qdf_event_create(&tran->event);
327*5113495bSYour Name 
328*5113495bSYour Name 	status = __dsc_dbg_tran_wait_timeout_start(tran);
329*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
330*5113495bSYour Name 		goto event_destroy;
331*5113495bSYour Name 
332*5113495bSYour Name 	qdf_list_insert_back(&trans->queue, &tran->node);
333*5113495bSYour Name 
334*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
335*5113495bSYour Name 
336*5113495bSYour Name event_destroy:
337*5113495bSYour Name 	qdf_event_destroy(&tran->event);
338*5113495bSYour Name 
339*5113495bSYour Name 	return status;
340*5113495bSYour Name }
341*5113495bSYour Name 
342*5113495bSYour Name /**
343*5113495bSYour Name  * __dsc_trans_dequeue() - dequeue the next queued transition from @trans
344*5113495bSYour Name  * @trans: the transactions container to dequeue from
345*5113495bSYour Name  *
346*5113495bSYour Name  * Return: the dequeued transition, or NULL if @trans is empty
347*5113495bSYour Name  */
__dsc_trans_dequeue(struct dsc_trans * trans)348*5113495bSYour Name static struct dsc_tran *__dsc_trans_dequeue(struct dsc_trans *trans)
349*5113495bSYour Name {
350*5113495bSYour Name 	QDF_STATUS status;
351*5113495bSYour Name 	qdf_list_node_t *node;
352*5113495bSYour Name 	struct dsc_tran *tran;
353*5113495bSYour Name 
354*5113495bSYour Name 	status = qdf_list_remove_front(&trans->queue, &node);
355*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
356*5113495bSYour Name 		return NULL;
357*5113495bSYour Name 
358*5113495bSYour Name 	tran = qdf_container_of(node, struct dsc_tran, node);
359*5113495bSYour Name 	__dsc_dbg_tran_wait_timeout_stop(tran);
360*5113495bSYour Name 
361*5113495bSYour Name 	return tran;
362*5113495bSYour Name }
363*5113495bSYour Name 
__dsc_trans_abort(struct dsc_trans * trans)364*5113495bSYour Name bool __dsc_trans_abort(struct dsc_trans *trans)
365*5113495bSYour Name {
366*5113495bSYour Name 	struct dsc_tran *tran;
367*5113495bSYour Name 
368*5113495bSYour Name 	tran = __dsc_trans_dequeue(trans);
369*5113495bSYour Name 	if (!tran)
370*5113495bSYour Name 		return false;
371*5113495bSYour Name 
372*5113495bSYour Name 	tran->abort = true;
373*5113495bSYour Name 	qdf_event_set(&tran->event);
374*5113495bSYour Name 
375*5113495bSYour Name 	return true;
376*5113495bSYour Name }
377*5113495bSYour Name 
__dsc_trans_trigger(struct dsc_trans * trans)378*5113495bSYour Name bool __dsc_trans_trigger(struct dsc_trans *trans)
379*5113495bSYour Name {
380*5113495bSYour Name 	struct dsc_tran *tran;
381*5113495bSYour Name 
382*5113495bSYour Name 	tran = __dsc_trans_dequeue(trans);
383*5113495bSYour Name 	if (!tran)
384*5113495bSYour Name 		return false;
385*5113495bSYour Name 
386*5113495bSYour Name 	__dsc_trans_start(trans, tran->desc);
387*5113495bSYour Name 	qdf_event_set(&tran->event);
388*5113495bSYour Name 
389*5113495bSYour Name 	return true;
390*5113495bSYour Name }
391*5113495bSYour Name 
__dsc_trans_active(struct dsc_trans * trans)392*5113495bSYour Name bool __dsc_trans_active(struct dsc_trans *trans)
393*5113495bSYour Name {
394*5113495bSYour Name 	return !!trans->active_desc;
395*5113495bSYour Name }
396*5113495bSYour Name 
__dsc_trans_queued(struct dsc_trans * trans)397*5113495bSYour Name bool __dsc_trans_queued(struct dsc_trans *trans)
398*5113495bSYour Name {
399*5113495bSYour Name 	return !qdf_list_empty(&trans->queue);
400*5113495bSYour Name }
401*5113495bSYour Name 
__dsc_trans_active_or_queued(struct dsc_trans * trans)402*5113495bSYour Name bool __dsc_trans_active_or_queued(struct dsc_trans *trans)
403*5113495bSYour Name {
404*5113495bSYour Name 	return __dsc_trans_active(trans) || __dsc_trans_queued(trans);
405*5113495bSYour Name }
406*5113495bSYour Name 
__dsc_tran_wait(struct dsc_tran * tran)407*5113495bSYour Name QDF_STATUS __dsc_tran_wait(struct dsc_tran *tran)
408*5113495bSYour Name {
409*5113495bSYour Name 	QDF_STATUS status;
410*5113495bSYour Name 
411*5113495bSYour Name 	status = qdf_wait_single_event(&tran->event, 0);
412*5113495bSYour Name 	qdf_event_destroy(&tran->event);
413*5113495bSYour Name 
414*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
415*5113495bSYour Name 		return status;
416*5113495bSYour Name 
417*5113495bSYour Name 	if (tran->abort)
418*5113495bSYour Name 		return QDF_STATUS_E_ABORTED;
419*5113495bSYour Name 
420*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
421*5113495bSYour Name }
422*5113495bSYour Name 
423