aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/include/dspbridge/list.h
blob: 6837b614073a828cac0626d5dd8bdc565503c5f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
 * list.h
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Declarations of list management control structures and definitions
 * of inline list management functions.
 *
 * Copyright (C) 2008 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef LIST_
#define LIST_

#include <dspbridge/host_os.h>
#include <linux/list.h>

#define LST_IS_EMPTY(l)      list_empty(&(l)->head)

struct lst_list {
	struct list_head head;
};

/*
 *  ======== lst_first ========
 *  Purpose:
 *      Returns a pointer to the first element of the list, or NULL if the list
 *      is empty.
 *  Parameters:
 *      lst:  Pointer to list control structure.
 *  Returns:
 *      Pointer to first list element, or NULL.
 *  Requires:
 *      - LST initialized.
 *      - lst != NULL.
 *  Ensures:
 */
static inline struct list_head *lst_first(struct lst_list *lst)
{
	if (lst && !list_empty(&lst->head))
		return lst->head.next;
	return NULL;
}

/*
 *  ======== lst_get_head ========
 *  Purpose:
 *      Pops the head off the list and returns a pointer to it.
 *  Details:
 *      If the list is empty, returns NULL.
 *      Else, removes the element at the head of the list, making the next
 *      element the head of the list.
 *      The head is removed by making the tail element of the list point its
 *      "next" pointer at the next element after the head, and by making the
 *      "prev" pointer of the next element after the head point at the tail
 *      element.  So the next element after the head becomes the new head of
 *      the list.
 *  Parameters:
 *      lst:    Pointer to list control structure of list whose head
 *              element is to be removed
 *  Returns:
 *      Pointer to element that was at the head of the list (success)
 *      NULL          No elements in list
 *  Requires:
 *      - LST initialized.
 *      - lst != NULL.
 *  Ensures:
 *  Notes:
 *      Because the tail of the list points forward (its "next" pointer) to
 *      the head of the list, and the head of the list points backward (its
 *      "prev" pointer) to the tail of the list, this list is circular.
 */
static inline struct list_head *lst_get_head(struct lst_list *lst)
{
	struct list_head *elem_list;

	if (!lst || list_empty(&lst->head))
		return NULL;

	elem_list = lst->head.next;
	lst->head.next = elem_list->next;
	elem_list->next->prev = &lst->head;

	return elem_list;
}

/*
 *  ======== lst_init_elem ========
 *  Purpose:
 *      Initializes a list element to default (cleared) values
 *  Details:
 *  Parameters:
 *      elem_list:  Pointer to list element to be reset
 *  Returns:
 *  Requires:
 *      LST initialized.
 *  Ensures:
 *  Notes:
 *      This function must not be called to "reset" an element in the middle
 *      of a list chain -- that would break the chain.
 *
 */
static inline void lst_init_elem(struct list_head *elem_list)
{
	if (elem_list) {
		elem_list->next = NULL;
		elem_list->prev = NULL;
	}
}

/*
 *  ======== lst_insert_before ========
 *  Purpose:
 *     Insert the element before the existing element.
 *  Parameters:
 *      lst:            Pointer to list control structure.
 *      elem_list:          Pointer to element in list to insert.
 *      elem_existing:  Pointer to existing list element.
 *  Returns:
 *  Requires:
 *      - LST initialized.
 *      - lst != NULL.
 *      - elem_list != NULL.
 *      - elem_existing != NULL.
 *  Ensures:
 */
static inline void lst_insert_before(struct lst_list *lst,
				     struct list_head *elem_list,
				     struct list_head *elem_existing)
{
	if (lst && elem_list && elem_existing)
		list_add_tail(elem_list, elem_existing);
}

/*
 *  ======== lst_next ========
 *  Purpose:
 *      Returns a pointer to the next element of the list, or NULL if the next
 *      element is the head of the list or the list is empty.
 *  Parameters:
 *      lst:        Pointer to list control structure.
 *      cur_elem:   Pointer to element in list to remove.
 *  Returns:
 *      Pointer to list element, or NULL.
 *  Requires:
 *      - LST initialized.
 *      - lst != NULL.
 *      - cur_elem != NULL.
 *  Ensures:
 */
static inline struct list_head *lst_next(struct lst_list *lst,
					 struct list_head *cur_elem)
{
	if (lst && !list_empty(&lst->head) && cur_elem &&
	    (cur_elem->next != &lst->head))
		return cur_elem->next;
	return NULL;
}

/*
 *  ======== lst_put_tail ========
 *  Purpose:
 *      Adds the specified element to the tail of the list
 *  Details:
 *      Sets new element's "prev" pointer to the address previously held by
 *      the head element's prev pointer.  This is the previous tail member of
 *      the list.
 *      Sets the new head's prev pointer to the address of the element.
 *      Sets next pointer of the previous tail member of the list to point to
 *      the new element (rather than the head, which it had been pointing at).
 *      Sets new element's next pointer to the address of the head element.
 *      Sets head's prev pointer to the address of the new element.
 *  Parameters:
 *      lst:    Pointer to list control structure to which *elem_list will be
 *              added
 *      elem_list:  Pointer to list element to be added
 *  Returns:
 *      Void
 *  Requires:
 *      *elem_list and *lst must both exist.
 *      LST initialized.
 *  Ensures:
 *  Notes:
 *      Because the tail is always "just before" the head of the list (the
 *      tail's "next" pointer points at the head of the list, and the head's
 *      "prev" pointer points at the tail of the list), the list is circular.
 */
static inline void lst_put_tail(struct lst_list *lst,
				struct list_head *elem_list)
{
	if (lst && elem_list)
		list_add_tail(elem_list, &lst->head);
}

/*
 *  ======== lst_remove_elem ========
 *  Purpose:
 *      Removes (unlinks) the given element from the list, if the list is not
 *      empty.  Does not free the list element.
 *  Parameters:
 *      lst:        Pointer to list control structure.
 *      cur_elem:   Pointer to element in list to remove.
 *  Returns:
 *  Requires:
 *      - LST initialized.
 *      - lst != NULL.
 *      - cur_elem != NULL.
 *  Ensures:
 */
static inline void lst_remove_elem(struct lst_list *lst,
				   struct list_head *cur_elem)
{
	if (lst && !list_empty(&lst->head) && cur_elem)
		list_del_init(cur_elem);
}

#endif /* LIST_ */