blob: 14e6d59f6f956ae5f7db73c314a603b80b9fbaa4 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/**=============================================================================
23
24 vos_list.c
25
26 \brief
27
28 Description...
29
30
31 Copyright 2008 (c) Qualcomm, Incorporated.
32 All Rights Reserved.
33 Qualcomm Confidential and Proprietary.
34
35 ==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39 Include files
40 ----------------------------------------------------------------------------*/
41#include <vos_list.h>
42#include <vos_trace.h>
43
44/**-----------------------------------------------------------------------------
45 Preprocessor definitions and constants
46 ----------------------------------------------------------------------------*/
47#define VOS_LIST_COOKIE 0xabadfeed
48
49
50/**-----------------------------------------------------------------------------
51 Type declarations
52 ----------------------------------------------------------------------------*/
53
54/**-----------------------------------------------------------------------------
55 Function declarations and documenation
56 ----------------------------------------------------------------------------*/
57VOS_STATUS vos_list_init( vos_list_t *pList )
58{
59 if ( pList == NULL)
60 {
61 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
62 "%s: NULL pointer passed in", __FUNCTION__);
63 return VOS_STATUS_E_FAULT;
64 }
65
66 if ( pList->cookie == VOS_LIST_COOKIE )
67 {
68 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
69 "%s: already initialized list", __FUNCTION__);
70 return VOS_STATUS_E_BUSY;
71 }
72
73 mutex_init(&pList->lock);
74
75 INIT_LIST_HEAD( &pList->anchor );
76
77 pList->count = 0;
78 pList->cookie = VOS_LIST_COOKIE;
79
80 return( VOS_STATUS_SUCCESS );
81}
82
83
84VOS_STATUS vos_list_destroy( vos_list_t *pList )
85{
86 int rc;
87 if (pList == NULL)
88 {
89 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
90 "%s: NULL pointer passed in", __FUNCTION__);
91 return VOS_STATUS_E_FAULT;
92 }
93
94 if ( pList->cookie != VOS_LIST_COOKIE )
95 {
96 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
97 "%s: list not initialized", __FUNCTION__);
98 return VOS_STATUS_E_INVAL;
99 }
100
101 rc = mutex_lock_interruptible(&pList->lock);
102 if (rc)
103 {
104 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
105 "%s: unable to lock list", __FUNCTION__);
106 return VOS_STATUS_E_FAULT;
107 }
108
109 if ( pList->count !=0 )
110 {
111 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
112 "%s: list length not equal to zero", __FUNCTION__);
113 mutex_unlock(&pList->lock);
114 return VOS_STATUS_E_BUSY;
115 }
116
117 // clear the cookie. This indicates the list is destroyed.
118 pList->cookie = 0;
119 mutex_unlock(&pList->lock);
120
121 return VOS_STATUS_SUCCESS;
122}
123
124
125VOS_STATUS vos_list_insert_front( vos_list_t *pList, vos_list_node_t *pNode )
126{
127 int rc;
128
129 if ( ( pList == NULL) || ( pNode == NULL) )
130 {
131 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
132 "%s: NULL pointer passed in", __FUNCTION__);
133 return VOS_STATUS_E_FAULT;
134 }
135
136 if ( pList->cookie != VOS_LIST_COOKIE )
137 {
138 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
139 "%s: list not initialized", __FUNCTION__);
140 return VOS_STATUS_E_INVAL;
141 }
142
143 rc = mutex_lock_interruptible(&pList->lock);
144 if (rc)
145 {
146 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
147 "%s: unable to lock list", __FUNCTION__);
148 return VOS_STATUS_E_FAULT;
149 }
150
151 list_add( pNode, &pList->anchor );
152
153 pList->count++;
154 mutex_unlock(&pList->lock);
155
156 return VOS_STATUS_SUCCESS;
157}
158
159VOS_STATUS vos_list_insert_back( vos_list_t *pList, vos_list_node_t *pNode )
160{
161 int rc;
162
163 if ( ( pList == NULL) || ( pNode == NULL) )
164 {
165 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
166 "%s: NULL pointer passed in", __FUNCTION__);
167 return VOS_STATUS_E_FAULT;
168 }
169
170 if ( pList->cookie != VOS_LIST_COOKIE )
171 {
172 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
173 "%s: list not initialized", __FUNCTION__);
174 return VOS_STATUS_E_INVAL;
175 }
176
177 rc = mutex_lock_interruptible(&pList->lock);
178 if (rc)
179 {
180 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
181 "%s: unable to lock list", __FUNCTION__);
182 return VOS_STATUS_E_FAULT;
183 }
184
185 list_add_tail( pNode, &pList->anchor );
186
187 pList->count++;
188 mutex_unlock(&pList->lock);
189
190 return VOS_STATUS_SUCCESS;
191}
192
193
194VOS_STATUS vos_list_insert_back_size( vos_list_t *pList, vos_list_node_t *pNode, v_SIZE_t *pSize )
195{
196 int rc;
197 if ( ( pList == NULL) || ( pNode == NULL) || (pSize == NULL) )
198 {
199 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
200 "%s: NULL pointer passed in", __FUNCTION__);
201 return VOS_STATUS_E_FAULT;
202 }
203
204 if ( pList->cookie != VOS_LIST_COOKIE )
205 {
206 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
207 "%s: list not initialized", __FUNCTION__);
208 return VOS_STATUS_E_INVAL;
209 }
210
211 rc = mutex_lock_interruptible(&pList->lock);
212 if (rc)
213 {
214 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
215 "%s: unable to lock list", __FUNCTION__);
216 return VOS_STATUS_E_FAULT;
217 }
218
219 list_add_tail( pNode, &pList->anchor );
220
221 pList->count++;
222 *pSize = pList->count;
223 mutex_unlock(&pList->lock);
224
225 return VOS_STATUS_SUCCESS;
226}
227
228
229VOS_STATUS vos_list_remove_front( vos_list_t *pList, vos_list_node_t **ppNode )
230{
231 struct list_head * listptr;
232 int rc;
233
234 // the assumption here is that pList is the head of the list (dummy
235 // node) and points to first and last element in circular linked list
236 if ( ( pList == NULL ) || ( ppNode == NULL) )
237 {
238 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
239 "%s: NULL pointer passed in", __FUNCTION__);
240 return VOS_STATUS_E_FAULT;
241 }
242
243 if ( pList->cookie != VOS_LIST_COOKIE )
244 {
245 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
246 "%s: list not initialized", __FUNCTION__);
247 return VOS_STATUS_E_INVAL;
248 }
249
250 rc = mutex_lock_interruptible(&pList->lock);
251 if (rc)
252 {
253 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
254 "%s: unable to lock list", __FUNCTION__);
255 return VOS_STATUS_E_FAULT;
256 }
257
258 if ( list_empty( &pList->anchor ) )
259 {
260 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
261 "%s: list empty", __FUNCTION__);
262 mutex_unlock(&pList->lock);
263 return VOS_STATUS_E_EMPTY;
264 }
265
266 listptr = pList->anchor.next;
267
268 *ppNode = listptr;
269
270 list_del(pList->anchor.next);
271
272 pList->count--;
273 mutex_unlock(&pList->lock);
274 return VOS_STATUS_SUCCESS;
275}
276
277
278
279VOS_STATUS vos_list_remove_back( vos_list_t *pList, vos_list_node_t **ppNode )
280{
281 struct list_head * listptr;
282 int rc;
283
284 // the assumption here is that pList is the head of the list (dummy node) and points to first and
285 // last element in circular linked list
286 if ( ( pList == NULL ) || ( ppNode == NULL) )
287 {
288 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
289 "%s: NULL pointer passed in", __FUNCTION__);
290 return VOS_STATUS_E_FAULT;
291 }
292
293 if ( pList->cookie != VOS_LIST_COOKIE )
294 {
295 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
296 "%s: list not initialized", __FUNCTION__);
297 return VOS_STATUS_E_INVAL;
298 }
299
300 rc = mutex_lock_interruptible(&pList->lock);
301 if (rc)
302 {
303 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
304 "%s: unable to lock list", __FUNCTION__);
305 return VOS_STATUS_E_FAULT;
306 }
307
308 if ( list_empty( &pList->anchor ) )
309 {
310 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
311 "%s: list empty", __FUNCTION__);
312 mutex_unlock(&pList->lock);
313 return VOS_STATUS_E_EMPTY;
314 }
315
316 listptr = pList->anchor.prev;
317
318 *ppNode = listptr;
319
320 list_del(pList->anchor.prev);
321
322 pList->count--;
323 mutex_unlock(&pList->lock);
324
325 return VOS_STATUS_SUCCESS;
326}
327
328VOS_STATUS vos_list_size( vos_list_t *pList, v_SIZE_t *pSize )
329{
330 int rc;
331 if ( ( pList ==NULL) || ( pSize == NULL) )
332 {
333 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
334 "%s: NULL pointer passed in", __FUNCTION__);
335 return VOS_STATUS_E_FAULT;
336 }
337
338 if ( pList->cookie != VOS_LIST_COOKIE )
339 {
340 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
341 "%s: list not initialized", __FUNCTION__);
342 return VOS_STATUS_E_INVAL;
343 }
344
345 rc = mutex_lock_interruptible(&pList->lock);
346 if (rc)
347 {
348 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
349 "%s: unable to lock list", __FUNCTION__);
350 return VOS_STATUS_E_FAULT;
351 }
352
353 *pSize = pList->count;
354 mutex_unlock(&pList->lock);
355
356 return VOS_STATUS_SUCCESS;
357}
358
359
360/*----------------------------------------------------------------------------
361
362 \brief vos_list_peek_front() - peek at the node at front of a linked list
363
364 The vos_list_peek_front() API will return a pointer to the node at the
365 front of a properly initialized vOS List object. The node will *not* be
366 removed from the list.
367
368 \param pList - Pointer to list object of the list to be 'peeked'
369
370 \param ppNode - Pointer to a pointer to the list node that exists at
371 the front of the list.
372
373 \return VOS_STATUS_SUCCESS - list node at the front of the list was
374 successfully returned.
375
376 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
377 initialized list object.
378
379 VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be
380 removed.
381
382 VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer.
383
384 \sa vos_list_remove_back()
385
386 --------------------------------------------------------------------------*/
387
388VOS_STATUS vos_list_peek_front( vos_list_t *pList, vos_list_node_t **ppNode )
389{
390 struct list_head * listptr;
391 int rc;
392
393 if ( ( pList == NULL) || ( ppNode == NULL) )
394 {
395 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
396 "%s: NULL pointer passed in", __FUNCTION__);
397 return VOS_STATUS_E_FAULT;
398 }
399
400 if ( pList->cookie != VOS_LIST_COOKIE )
401 {
402 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
403 "%s: list not initialized", __FUNCTION__);
404 return VOS_STATUS_E_INVAL;
405 }
406
407 rc = mutex_lock_interruptible(&pList->lock);
408 if (rc)
409 {
410 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
411 "%s: unable to lock list", __FUNCTION__);
412 return VOS_STATUS_E_FAULT;
413 }
414
415 if ( list_empty(&pList->anchor) )
416 {
417 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
418 "%s: list empty", __FUNCTION__);
419 mutex_unlock(&pList->lock);
420 return VOS_STATUS_E_EMPTY;
421 }
422 listptr = pList->anchor.next;
423 *ppNode = listptr;
424 mutex_unlock(&pList->lock);
425
426 return VOS_STATUS_SUCCESS;
427}
428
429/*----------------------------------------------------------------------------
430
431 \brief vos_list_peek_back() - peek at the node at back of a linked list
432
433 The vos_list_peek_back() API will return a pointer to the node at the
434 back of a properly initialized vOS List object. The node will *not* be
435 removed from the list.
436
437 \param pList - Pointer to list object of the list to be 'peeked'
438
439 \param ppNode - Pointer to a pointer to the list node that exists at
440 the back of the list.
441
442 \return VOS_STATUS_SUCCESS - list node at the back of the list was
443 successfully returned.
444
445 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
446 initialized list object.
447
448 VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be
449 removed.
450
451 VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer.
452
453 \sa vos_list_peek_back(), vos_list_remove_back(), vos_list_peek_front(),
454 vos_list_remove_front()
455
456 --------------------------------------------------------------------------*/
457
458VOS_STATUS vos_list_peek_back( vos_list_t *pList, vos_list_node_t **ppNode )
459{
460 struct list_head * listptr;
461 int rc;
462
463 if ( ( pList == NULL) || ( ppNode == NULL) )
464 {
465 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
466 "%s: NULL pointer passed in", __FUNCTION__);
467 return VOS_STATUS_E_FAULT;
468 }
469
470 if ( pList->cookie != VOS_LIST_COOKIE )
471 {
472 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
473 "%s: list not initialized", __FUNCTION__);
474 return VOS_STATUS_E_INVAL;
475 }
476
477 rc = mutex_lock_interruptible(&pList->lock);
478 if (rc)
479 {
480 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
481 "%s: unable to lock list", __FUNCTION__);
482 return VOS_STATUS_E_FAULT;
483 }
484
485 if ( list_empty(&pList->anchor) )
486 {
487 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
488 "%s: list empty", __FUNCTION__);
489 mutex_unlock(&pList->lock);
490 return VOS_STATUS_E_EMPTY;
491 }
492 listptr = pList->anchor.prev;
493 *ppNode = listptr;
494 mutex_unlock(&pList->lock);
495
496 return VOS_STATUS_SUCCESS;
497}
498
499/*----------------------------------------------------------------------------
500
501 \brief vos_list_peek_next() - peek at the node after the specified node
502
503 The vos_list_peek_next() API will return a pointer to the node following the
504 specified node on a properly initialized vOS List object. The node will
505 *not* be removed from the list.
506
507 \param pList - Pointer to list object of the list to be 'peeked'
508
509 \param pNode - Pointer to the node that is being 'peeked'
510
511 \param ppNode - Pointer to a pointer to the list node that follows the
512 pNode node on the list.
513
514 \return VOS_STATUS_SUCCESS - list node following pNode on the properly
515 initialized list is successfully returned.
516
517 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
518 initialized list object.
519
520 VOS_STATUS_E_EMPTY - There is no 'next' node (the input node is
521 at the back of the list).
522
523 VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer.
524
525 \sa vos_list_remove_back()
526
527 --------------------------------------------------------------------------*/
528
529VOS_STATUS vos_list_peek_next( vos_list_t *pList, vos_list_node_t *pNode,
530 vos_list_node_t **ppNode )
531{
532 struct list_head * listptr;
533 int rc, found = 0;
534 vos_list_node_t *tmp;
535
536 if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL))
537 {
538 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
539 "%s: NULL pointer passed in", __FUNCTION__);
540 return VOS_STATUS_E_FAULT;
541 }
542
543 if ( pList->cookie != VOS_LIST_COOKIE )
544 {
545 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
546 "%s: list not initialized", __FUNCTION__);
547 return VOS_STATUS_E_INVAL;
548 }
549
550 rc = mutex_lock_interruptible(&pList->lock);
551 if (rc)
552 {
553 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
554 "%s: unable to lock list", __FUNCTION__);
555 return VOS_STATUS_E_FAULT;
556 }
557
558 if ( list_empty(&pList->anchor) )
559 {
560 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
561 "%s: list empty", __FUNCTION__);
562 mutex_unlock(&pList->lock);
563 return VOS_STATUS_E_EMPTY;
564 }
565
566 // verify that pNode is indeed part of list pList
567 list_for_each(tmp, &pList->anchor)
568 {
569 if (tmp == pNode)
570 {
571 found = 1;
572 break;
573 }
574 }
575 if (found == 0)
576 return VOS_STATUS_E_INVAL;
577
578 listptr = pNode->next;
579 if (listptr == &pList->anchor)
580 {
581 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
582 "%s: list empty", __FUNCTION__);
583 mutex_unlock(&pList->lock);
584 return VOS_STATUS_E_EMPTY;
585 }
586
587 *ppNode = listptr;
588 mutex_unlock(&pList->lock);
589
590 return VOS_STATUS_SUCCESS;
591}
592
593/*----------------------------------------------------------------------------
594
595 \brief vos_list_peek_prev() - peek at the node before the specified node
596
597 The vos_list_peek_prev() API will return a pointer to the node before the
598 specified node on a properly initialized vOS List object. The node will
599 *not* be removed from the list.
600
601 \param pList - Pointer to list object of the list to be 'peeked'
602
603 \param pNode - Pointer to the node that is being 'peeked'
604
605 \param ppNode - Pointer to a pointer to the list node before the
606 pNode node on the list.
607
608 \return VOS_STATUS_SUCCESS - list node before pNode on the properly
609 initialized list is successfully returned.
610
611 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
612 initialized list object.
613
614 VOS_STATUS_E_EMPTY - There is no 'previous' node (the input node is
615 at the front of the list).
616
617 VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer.
618
619 \sa vos_list_remove_back()
620
621 --------------------------------------------------------------------------*/
622
623VOS_STATUS vos_list_peek_prev( vos_list_t *pList, vos_list_node_t *pNode,
624 vos_list_node_t **ppNode )
625{
626 struct list_head * listptr;
627 int rc, found = 0;
628 vos_list_node_t *tmp;
629
630 if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL) )
631 {
632 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
633 "%s: NULL pointer passed in", __FUNCTION__);
634 return VOS_STATUS_E_FAULT;
635 }
636
637 if ( pList->cookie != VOS_LIST_COOKIE )
638 {
639 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
640 "%s: list not initialized", __FUNCTION__);
641 return VOS_STATUS_E_INVAL;
642 }
643
644 rc = mutex_lock_interruptible(&pList->lock);
645 if (rc)
646 {
647 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
648 "%s: unable to lock list", __FUNCTION__);
649 return VOS_STATUS_E_FAULT;
650 }
651
652 if ( list_empty(&pList->anchor) )
653 {
654 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
655 "%s: list empty", __FUNCTION__);
656 mutex_unlock(&pList->lock);
657 return VOS_STATUS_E_EMPTY;
658 }
659
660 // verify that pNode is indeed part of list pList
661 list_for_each(tmp, &pList->anchor)
662 {
663 if (tmp == pNode)
664 {
665 found = 1;
666 break;
667 }
668 }
669 if (found == 0)
670 return VOS_STATUS_E_INVAL;
671
672 listptr = pNode->prev;
673
674 if (listptr == &pList->anchor)
675 {
676 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
677 "%s: list empty", __FUNCTION__);
678 mutex_unlock(&pList->lock);
679 return VOS_STATUS_E_EMPTY;
680 }
681
682 *ppNode = listptr;
683 mutex_unlock(&pList->lock);
684
685 return VOS_STATUS_SUCCESS;
686}
687
688/*----------------------------------------------------------------------------
689
690 \brief vos_list_insert_before() - insert node at front of a specified
691 list node
692
693 The vos_list_insert_before() API will insert a node onto a properly
694 initialized vOS List object in front of the specified list node.
695
696 \param pList - Pointer to list object where the node will be inserted
697
698 \param pNodeToInsert - Pointer to the list node to be inserted into the list.
699
700 \param pNode - Pointer to the list node where pNodeToInsert will be inserted
701 in front of.
702
703 \return VOS_STATUS_SUCCESS - list node was successfully inserted onto
704 the front of the list.
705
706 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
707 initialized list object.
708
709 VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are
710 invalid pointer(s)
711
712 \sa
713
714 --------------------------------------------------------------------------*/
715VOS_STATUS vos_list_insert_before( vos_list_t *pList, vos_list_node_t *pNodeToInsert,
716 vos_list_node_t *pNode )
717{
718 int rc, found = 0;
719 vos_list_node_t *tmp;
720
721 if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL))
722 {
723 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
724 "%s: NULL pointer passed in", __FUNCTION__);
725 return VOS_STATUS_E_FAULT;
726 }
727
728 if ( pList->cookie != VOS_LIST_COOKIE )
729 {
730 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list not initialized", __FUNCTION__);
731 return VOS_STATUS_E_INVAL;
732 }
733
734 rc = mutex_lock_interruptible(&pList->lock);
735 if (rc)
736 {
737 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
738 "%s: unable to lock list", __FUNCTION__);
739 return VOS_STATUS_E_FAULT;
740 }
741
742 if ( list_empty(&pList->anchor) )
743 {
744 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list empty", __FUNCTION__);
745 mutex_unlock(&pList->lock);
746 return VOS_STATUS_E_EMPTY;
747 }
748
749 // verify that pNode is indeed part of list pList
750 list_for_each(tmp, &pList->anchor)
751 {
752 if (tmp == pNode)
753 {
754 found = 1;
755 break;
756 }
757 }
758 if (found == 0)
759 return VOS_STATUS_E_INVAL;
760
761 list_add(pNodeToInsert, pNode);
762 pList->count++;
763 mutex_unlock(&pList->lock);
764
765 return VOS_STATUS_SUCCESS;
766}
767
768
769/*----------------------------------------------------------------------------
770
771 \brief vos_list_insert_after() - insert node behind a specified list node
772
773 The vos_list_insert_after() API will insert a node onto a properly
774 initialized vOS List object after the specified list node.
775
776 \param pList - Pointer to list object where the node will be inserted
777
778 \param pNodeToInsert - Pointer to the list node to be inserted into the list.
779
780 \param pNode - Pointer to the list node where pNodeToInsert will be inserted
781 after.
782
783 \return VOS_STATUS_SUCCESS - list node was successfully inserted onto
784 the front of the list.
785
786 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
787 initialized list object.
788
789 VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are
790 invalid pointer(s)
791
792 \sa
793
794 --------------------------------------------------------------------------*/
795VOS_STATUS vos_list_insert_after( vos_list_t *pList, vos_list_node_t *pNodeToInsert,
796 vos_list_node_t *pNode )
797{
798 int rc, found = 0;
799 vos_list_node_t *tmp;
800
801 if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL))
802 {
803 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
804 "%s: NULL pointer passed in", __FUNCTION__);
805 return VOS_STATUS_E_FAULT;
806 }
807
808 if ( pList->cookie != VOS_LIST_COOKIE )
809 {
810 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
811 "%s: list not initialized", __FUNCTION__);
812 return VOS_STATUS_E_INVAL;
813 }
814
815 rc = mutex_lock_interruptible(&pList->lock);
816 if (rc)
817 {
818 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
819 "%s: unable to lock list", __FUNCTION__);
820 return VOS_STATUS_E_FAULT;
821 }
822
823
824 if ( list_empty(&pList->anchor) )
825 {
826 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
827 "%s: list empty", __FUNCTION__);
828 mutex_unlock(&pList->lock);
829 return VOS_STATUS_E_EMPTY;
830 }
831
832 // verify that pNode is indeed part of list pList
833 list_for_each(tmp, &pList->anchor)
834 {
835 if (tmp == pNode)
836 {
837 found = 1;
838 break;
839 }
840 }
841 if (found == 0)
842 return VOS_STATUS_E_INVAL;
843
844 list_add_tail(pNodeToInsert, pNode);
845 pList->count++;
846 mutex_unlock(&pList->lock);
847
848 return VOS_STATUS_SUCCESS;
849}
850
851/*----------------------------------------------------------------------------
852
853 \brief vos_list_remove_node() - remove specified node from vOS list list
854
855 The vos_list_remove_node() API will remove a specified node from the
856 properly initialized vOS List object.
857
858 \param pList - Pointer to list object where the node will be removed
859
860 \param ppNode - Pointer to the node to be removed from the list.
861
862 \return VOS_STATUS_SUCCESS - list node was successfully removed from
863 the list.
864
865 VOS_STATUS_E_INVAL - The value specified by pList is not a valid,
866 initialized list object.
867
868 VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be
869 removed.
870
871
872 VOS_STATUS_E_FAULT - pList or pNodeToRemove is not a valid pointer
873
874 \sa
875
876 --------------------------------------------------------------------------*/
877VOS_STATUS vos_list_remove_node( vos_list_t *pList, vos_list_node_t *pNodeToRemove )
878{
879 int rc, found = 0;
880 vos_list_node_t *tmp;
881
882 if ( ( pList == NULL ) || ( pNodeToRemove == NULL) )
883 {
884 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
885 "%s: NULL pointer passed in", __FUNCTION__);
886 return VOS_STATUS_E_FAULT;
887 }
888
889 if ( pList->cookie != VOS_LIST_COOKIE )
890 {
891 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
892 "%s: list not initialized", __FUNCTION__);
893 return VOS_STATUS_E_INVAL;
894 }
895
896 rc = mutex_lock_interruptible(&pList->lock);
897 if (rc)
898 {
899 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
900 "%s: unable to lock list", __FUNCTION__);
901 return VOS_STATUS_E_FAULT;
902 }
903
904 if ( list_empty(&pList->anchor) )
905 {
906 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
907 "%s: list empty", __FUNCTION__);
908 mutex_unlock(&pList->lock);
909 return VOS_STATUS_E_EMPTY;
910 }
911
912 // verify that pNodeToRemove is indeed part of list pList
913 list_for_each(tmp, &pList->anchor)
914 {
915 if (tmp == pNodeToRemove)
916 {
917 found = 1;
918 break;
919 }
920 }
921 if (found == 0)
922 return VOS_STATUS_E_INVAL;
923
924 list_del(pNodeToRemove);
925 pList->count--;
926 mutex_unlock(&pList->lock);
927
928 return VOS_STATUS_SUCCESS;
929}