xref: /openbsd-src/sys/dev/pci/drm/include/linux/list.h (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: list.h,v 1.1 2019/04/14 10:14:53 jsg Exp $	*/
2 /* drm_linux_list.h -- linux list functions for the BSDs.
3  * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org
4  */
5 /*-
6  * Copyright 2003 Eric Anholt
7  * All Rights Reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  *
28  * Authors:
29  *    Eric Anholt <anholt@FreeBSD.org>
30  *
31  */
32 
33 #ifndef _DRM_LINUX_LIST_H_
34 #define _DRM_LINUX_LIST_H_
35 
36 #include <sys/param.h>
37 #include <linux/kernel.h>
38 #include <linux/types.h>
39 
40 #define list_entry(ptr, type, member) container_of(ptr, type, member)
41 
42 static inline void
43 INIT_LIST_HEAD(struct list_head *head) {
44 	(head)->next = head;
45 	(head)->prev = head;
46 }
47 
48 #define LIST_HEAD_INIT(name) { &(name), &(name) }
49 
50 #define DRM_LIST_HEAD(name) \
51 	struct list_head name = LIST_HEAD_INIT(name)
52 
53 static inline int
54 list_empty(const struct list_head *head) {
55 	return (head)->next == head;
56 }
57 
58 static inline int
59 list_is_singular(const struct list_head *head) {
60 	return !list_empty(head) && ((head)->next == (head)->prev);
61 }
62 
63 static inline int
64 list_is_last(const struct list_head *list,
65     const struct list_head *head)
66 {
67 	return list->next == head;
68 }
69 
70 static inline void
71 list_add(struct list_head *new, struct list_head *head) {
72         (head)->next->prev = new;
73         (new)->next = (head)->next;
74         (new)->prev = head;
75         (head)->next = new;
76 }
77 
78 static inline void
79 list_add_tail(struct list_head *entry, struct list_head *head) {
80 	(entry)->prev = (head)->prev;
81 	(entry)->next = head;
82 	(head)->prev->next = entry;
83 	(head)->prev = entry;
84 }
85 
86 static inline void
87 list_del(struct list_head *entry) {
88 	(entry)->next->prev = (entry)->prev;
89 	(entry)->prev->next = (entry)->next;
90 }
91 
92 #define __list_del_entry(x) list_del(x)
93 
94 static inline void list_replace(struct list_head *old,
95 				struct list_head *new)
96 {
97 	new->next = old->next;
98 	new->next->prev = new;
99 	new->prev = old->prev;
100 	new->prev->next = new;
101 }
102 
103 static inline void list_replace_init(struct list_head *old,
104 				     struct list_head *new)
105 {
106 	list_replace(old, new);
107 	INIT_LIST_HEAD(old);
108 }
109 
110 static inline void list_move(struct list_head *list, struct list_head *head)
111 {
112 	list_del(list);
113 	list_add(list, head);
114 }
115 
116 static inline void list_move_tail(struct list_head *list,
117     struct list_head *head)
118 {
119 	list_del(list);
120 	list_add_tail(list, head);
121 }
122 
123 static inline void
124 list_del_init(struct list_head *entry) {
125 	(entry)->next->prev = (entry)->prev;
126 	(entry)->prev->next = (entry)->next;
127 	INIT_LIST_HEAD(entry);
128 }
129 
130 #define list_next_entry(pos, member)				\
131 	list_entry(((pos)->member.next), typeof(*(pos)), member)
132 
133 #define list_prev_entry(pos, member)				\
134 	list_entry(((pos)->member.prev), typeof(*(pos)), member)
135 
136 #define list_for_each(entry, head)				\
137     for (entry = (head)->next; entry != head; entry = (entry)->next)
138 
139 #define list_for_each_prev(entry, head) \
140         for (entry = (head)->prev; entry != (head); \
141                 entry = entry->prev)
142 
143 #define list_for_each_safe(entry, temp, head)			\
144     for (entry = (head)->next, temp = (entry)->next;		\
145 	entry != head; 						\
146 	entry = temp, temp = entry->next)
147 
148 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
149 	for (pos = list_entry((head)->prev, __typeof(*pos), member),	\
150 	    n = list_entry((pos)->member.prev, __typeof(*pos), member);	\
151 	    &(pos)->member != (head);					\
152 	    pos = n, n = list_entry(n->member.prev, __typeof(*n), member))
153 
154 #define list_for_each_entry_safe_from(pos, n, head, member) 		\
155 	for (n = list_entry(pos->member.next, __typeof(*pos), member);	\
156 	     &pos->member != (head);					\
157 	     pos = n, n = list_entry(n->member.next, __typeof(*n), member))
158 
159 #define list_for_each_entry(pos, head, member)				\
160     for (pos = list_entry((head)->next, __typeof(*pos), member);	\
161 	&pos->member != (head);					 	\
162 	pos = list_entry(pos->member.next, __typeof(*pos), member))
163 
164 #define list_for_each_entry_from(pos, head, member)			\
165     for (;								\
166 	&pos->member != (head);					 	\
167 	pos = list_entry(pos->member.next, __typeof(*pos), member))
168 
169 #define list_for_each_entry_reverse(pos, head, member)			\
170     for (pos = list_entry((head)->prev, __typeof(*pos), member);	\
171 	&pos->member != (head);					 	\
172 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
173 
174 #define list_for_each_entry_from_reverse(pos, head, member)		\
175     for (;								\
176 	&pos->member != (head);					 	\
177 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
178 
179 #define list_for_each_entry_continue(pos, head, member)				\
180     for (pos = list_entry((pos)->member.next, __typeof(*pos), member);	\
181 	&pos->member != (head);					 	\
182 	pos = list_entry(pos->member.next, __typeof(*pos), member))
183 
184 #define list_for_each_entry_continue_reverse(pos, head, member)         \
185         for (pos = list_entry(pos->member.prev, __typeof(*pos), member);  \
186              &pos->member != (head);    				\
187              pos = list_entry(pos->member.prev, __typeof(*pos), member))
188 
189 /**
190  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
191  * @pos:        the type * to use as a loop cursor.
192  * @n:          another type * to use as temporary storage
193  * @head:       the head for your list.
194  * @member:     the name of the list_struct within the struct.
195  */
196 #define list_for_each_entry_safe(pos, n, head, member)			\
197 	for (pos = list_entry((head)->next, __typeof(*pos), member),	\
198 	    n = list_entry(pos->member.next, __typeof(*pos), member);	\
199 	    &pos->member != (head);					\
200 	    pos = n, n = list_entry(n->member.next, __typeof(*n), member))
201 
202 #define list_first_entry(ptr, type, member) \
203 	list_entry((ptr)->next, type, member)
204 
205 #define list_first_entry_or_null(ptr, type, member) \
206 	(list_empty(ptr) ? NULL : list_first_entry(ptr, type, member))
207 
208 #define list_last_entry(ptr, type, member) \
209 	list_entry((ptr)->prev, type, member)
210 
211 static inline void
212 __list_splice(const struct list_head *list, struct list_head *prev,
213     struct list_head *next)
214 {
215 	struct list_head *first = list->next;
216 	struct list_head *last = list->prev;
217 
218 	first->prev = prev;
219 	prev->next = first;
220 
221 	last->next = next;
222 	next->prev = last;
223 }
224 
225 static inline void
226 list_splice(const struct list_head *list, struct list_head *head)
227 {
228 	if (list_empty(list))
229 		return;
230 
231 	__list_splice(list, head, head->next);
232 }
233 
234 static inline void
235 list_splice_init(struct list_head *list, struct list_head *head)
236 {
237 	if (list_empty(list))
238 		return;
239 
240 	__list_splice(list, head, head->next);
241 	INIT_LIST_HEAD(list);
242 }
243 
244 static inline void
245 list_splice_tail(const struct list_head *list, struct list_head *head)
246 {
247 	if (list_empty(list))
248 		return;
249 
250 	__list_splice(list, head->prev, head);
251 }
252 
253 static inline void
254 list_splice_tail_init(struct list_head *list, struct list_head *head)
255 {
256 	if (list_empty(list))
257 		return;
258 
259 	__list_splice(list, head->prev, head);
260 	INIT_LIST_HEAD(list);
261 }
262 
263 void	list_sort(void *, struct list_head *,
264 	    int (*)(void *, struct list_head *, struct list_head *));
265 
266 #define hlist_entry(ptr, type, member) \
267 	((ptr) ? container_of(ptr, type, member) : NULL)
268 
269 static inline void
270 INIT_HLIST_HEAD(struct hlist_head *head) {
271 	head->first = NULL;
272 }
273 
274 static inline int
275 hlist_empty(const struct hlist_head *head) {
276 	return head->first == NULL;
277 }
278 
279 static inline void
280 hlist_add_head(struct hlist_node *new, struct hlist_head *head)
281 {
282 	if ((new->next = head->first) != NULL)
283 		head->first->prev = &new->next;
284 	head->first = new;
285 	new->prev = &head->first;
286 }
287 
288 static inline void
289 hlist_del_init(struct hlist_node *node)
290 {
291 	if (node->next != NULL)
292 		node->next->prev = node->prev;
293 	*(node->prev) = node->next;
294 	node->next = NULL;
295 	node->prev = NULL;
296 }
297 
298 #define hlist_for_each(pos, head) \
299 	for (pos = (head)->first; pos != NULL; pos = pos->next)
300 
301 #define hlist_for_each_entry(pos, head, member)				\
302 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
303 	     pos != NULL;						\
304 	     pos = hlist_entry((pos)->member.next, __typeof(*pos), member))
305 
306 #define hlist_for_each_entry_safe(pos, n, head, member)			\
307 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
308 	     pos != NULL && (n = pos->member.next, 1);			\
309 	     pos = hlist_entry(n, __typeof(*pos), member))
310 
311 #endif /* _DRM_LINUX_LIST_H_ */
312