xref: /openbsd-src/sys/dev/pci/drm/include/linux/list.h (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: list.h,v 1.2 2020/06/08 04:48:14 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 #include <linux/poison.h>
40 
41 #define list_entry(ptr, type, member) container_of(ptr, type, member)
42 
43 static inline void
44 INIT_LIST_HEAD(struct list_head *head) {
45 	(head)->next = head;
46 	(head)->prev = head;
47 }
48 
49 #define LIST_HEAD_INIT(name) { &(name), &(name) }
50 
51 #define DRM_LIST_HEAD(name) \
52 	struct list_head name = LIST_HEAD_INIT(name)
53 
54 static inline int
55 list_empty(const struct list_head *head) {
56 	return (head)->next == head;
57 }
58 
59 static inline int
60 list_is_singular(const struct list_head *head) {
61 	return !list_empty(head) && ((head)->next == (head)->prev);
62 }
63 
64 static inline int
65 list_is_first(const struct list_head *list,
66     const struct list_head *head)
67 {
68 	return list->prev == head;
69 }
70 
71 static inline int
72 list_is_last(const struct list_head *list,
73     const struct list_head *head)
74 {
75 	return list->next == head;
76 }
77 
78 static inline void
79 list_add(struct list_head *new, struct list_head *head) {
80         (head)->next->prev = new;
81         (new)->next = (head)->next;
82         (new)->prev = head;
83         (head)->next = new;
84 }
85 
86 static inline void
87 list_add_tail(struct list_head *entry, struct list_head *head) {
88 	(entry)->prev = (head)->prev;
89 	(entry)->next = head;
90 	(head)->prev->next = entry;
91 	(head)->prev = entry;
92 }
93 
94 static inline void
95 list_del(struct list_head *entry) {
96 	(entry)->next->prev = (entry)->prev;
97 	(entry)->prev->next = (entry)->next;
98 }
99 
100 #define __list_del_entry(x) list_del(x)
101 
102 static inline void list_replace(struct list_head *old,
103 				struct list_head *new)
104 {
105 	new->next = old->next;
106 	new->next->prev = new;
107 	new->prev = old->prev;
108 	new->prev->next = new;
109 }
110 
111 static inline void list_replace_init(struct list_head *old,
112 				     struct list_head *new)
113 {
114 	list_replace(old, new);
115 	INIT_LIST_HEAD(old);
116 }
117 
118 static inline void list_move(struct list_head *list, struct list_head *head)
119 {
120 	list_del(list);
121 	list_add(list, head);
122 }
123 
124 static inline void list_move_tail(struct list_head *list,
125     struct list_head *head)
126 {
127 	list_del(list);
128 	list_add_tail(list, head);
129 }
130 
131 static inline void
132 list_bulk_move_tail(struct list_head *head, struct list_head *first,
133     struct list_head *last)
134 {
135 	first->prev->next = last->next;
136 	last->next->prev = first->prev;
137 	head->prev->next = first;
138 	first->prev = head->prev;
139 	last->next = head;
140 	head->prev = last;
141 }
142 
143 static inline void
144 list_del_init(struct list_head *entry) {
145 	(entry)->next->prev = (entry)->prev;
146 	(entry)->prev->next = (entry)->next;
147 	INIT_LIST_HEAD(entry);
148 }
149 
150 #define list_next_entry(pos, member)				\
151 	list_entry(((pos)->member.next), typeof(*(pos)), member)
152 
153 #define list_prev_entry(pos, member)				\
154 	list_entry(((pos)->member.prev), typeof(*(pos)), member)
155 
156 #define list_safe_reset_next(pos, n, member)			\
157 	n = list_next_entry(pos, member)
158 
159 #define list_for_each(entry, head)				\
160     for (entry = (head)->next; entry != head; entry = (entry)->next)
161 
162 #define list_for_each_prev(entry, head) \
163         for (entry = (head)->prev; entry != (head); \
164                 entry = entry->prev)
165 
166 #define list_for_each_safe(entry, temp, head)			\
167     for (entry = (head)->next, temp = (entry)->next;		\
168 	entry != head; 						\
169 	entry = temp, temp = entry->next)
170 
171 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
172 	for (pos = list_entry((head)->prev, __typeof(*pos), member),	\
173 	    n = list_entry((pos)->member.prev, __typeof(*pos), member);	\
174 	    &(pos)->member != (head);					\
175 	    pos = n, n = list_entry(n->member.prev, __typeof(*n), member))
176 
177 #define list_for_each_entry_safe_from(pos, n, head, member) 		\
178 	for (n = list_entry(pos->member.next, __typeof(*pos), member);	\
179 	     &pos->member != (head);					\
180 	     pos = n, n = list_entry(n->member.next, __typeof(*n), member))
181 
182 #define list_for_each_entry(pos, head, member)				\
183     for (pos = list_entry((head)->next, __typeof(*pos), member);	\
184 	&pos->member != (head);					 	\
185 	pos = list_entry(pos->member.next, __typeof(*pos), member))
186 
187 #define list_for_each_entry_from(pos, head, member)			\
188     for (;								\
189 	&pos->member != (head);					 	\
190 	pos = list_entry(pos->member.next, __typeof(*pos), member))
191 
192 #define list_for_each_entry_reverse(pos, head, member)			\
193     for (pos = list_entry((head)->prev, __typeof(*pos), member);	\
194 	&pos->member != (head);					 	\
195 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
196 
197 #define list_for_each_entry_from_reverse(pos, head, member)		\
198     for (;								\
199 	&pos->member != (head);					 	\
200 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
201 
202 #define list_for_each_entry_continue(pos, head, member)				\
203     for (pos = list_entry((pos)->member.next, __typeof(*pos), member);	\
204 	&pos->member != (head);					 	\
205 	pos = list_entry(pos->member.next, __typeof(*pos), member))
206 
207 #define list_for_each_entry_continue_reverse(pos, head, member)         \
208         for (pos = list_entry(pos->member.prev, __typeof(*pos), member);  \
209              &pos->member != (head);    				\
210              pos = list_entry(pos->member.prev, __typeof(*pos), member))
211 
212 /**
213  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
214  * @pos:        the type * to use as a loop cursor.
215  * @n:          another type * to use as temporary storage
216  * @head:       the head for your list.
217  * @member:     the name of the list_struct within the struct.
218  */
219 #define list_for_each_entry_safe(pos, n, head, member)			\
220 	for (pos = list_entry((head)->next, __typeof(*pos), member),	\
221 	    n = list_entry(pos->member.next, __typeof(*pos), member);	\
222 	    &pos->member != (head);					\
223 	    pos = n, n = list_entry(n->member.next, __typeof(*n), member))
224 
225 #define list_first_entry(ptr, type, member) \
226 	list_entry((ptr)->next, type, member)
227 
228 #define list_first_entry_or_null(ptr, type, member) \
229 	(list_empty(ptr) ? NULL : list_first_entry(ptr, type, member))
230 
231 #define list_last_entry(ptr, type, member) \
232 	list_entry((ptr)->prev, type, member)
233 
234 static inline void
235 __list_splice(const struct list_head *list, struct list_head *prev,
236     struct list_head *next)
237 {
238 	struct list_head *first = list->next;
239 	struct list_head *last = list->prev;
240 
241 	first->prev = prev;
242 	prev->next = first;
243 
244 	last->next = next;
245 	next->prev = last;
246 }
247 
248 static inline void
249 list_splice(const struct list_head *list, struct list_head *head)
250 {
251 	if (list_empty(list))
252 		return;
253 
254 	__list_splice(list, head, head->next);
255 }
256 
257 static inline void
258 list_splice_init(struct list_head *list, struct list_head *head)
259 {
260 	if (list_empty(list))
261 		return;
262 
263 	__list_splice(list, head, head->next);
264 	INIT_LIST_HEAD(list);
265 }
266 
267 static inline void
268 list_splice_tail(const struct list_head *list, struct list_head *head)
269 {
270 	if (list_empty(list))
271 		return;
272 
273 	__list_splice(list, head->prev, head);
274 }
275 
276 static inline void
277 list_splice_tail_init(struct list_head *list, struct list_head *head)
278 {
279 	if (list_empty(list))
280 		return;
281 
282 	__list_splice(list, head->prev, head);
283 	INIT_LIST_HEAD(list);
284 }
285 
286 void	list_sort(void *, struct list_head *,
287 	    int (*)(void *, struct list_head *, struct list_head *));
288 
289 #define hlist_entry(ptr, type, member) \
290 	((ptr) ? container_of(ptr, type, member) : NULL)
291 
292 static inline void
293 INIT_HLIST_HEAD(struct hlist_head *head) {
294 	head->first = NULL;
295 }
296 
297 static inline int
298 hlist_empty(const struct hlist_head *head) {
299 	return head->first == NULL;
300 }
301 
302 static inline void
303 hlist_add_head(struct hlist_node *new, struct hlist_head *head)
304 {
305 	if ((new->next = head->first) != NULL)
306 		head->first->prev = &new->next;
307 	head->first = new;
308 	new->prev = &head->first;
309 }
310 
311 static inline void
312 hlist_del_init(struct hlist_node *node)
313 {
314 	if (node->next != NULL)
315 		node->next->prev = node->prev;
316 	*(node->prev) = node->next;
317 	node->next = NULL;
318 	node->prev = NULL;
319 }
320 
321 #define hlist_for_each(pos, head) \
322 	for (pos = (head)->first; pos != NULL; pos = pos->next)
323 
324 #define hlist_for_each_entry(pos, head, member)				\
325 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
326 	     pos != NULL;						\
327 	     pos = hlist_entry((pos)->member.next, __typeof(*pos), member))
328 
329 #define hlist_for_each_entry_safe(pos, n, head, member)			\
330 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
331 	     pos != NULL && (n = pos->member.next, 1);			\
332 	     pos = hlist_entry(n, __typeof(*pos), member))
333 
334 #endif /* _DRM_LINUX_LIST_H_ */
335