xref: /openbsd-src/sys/dev/pci/drm/include/linux/list.h (revision d89ec533011f513df1010f142a111086a0785f09)
1 /*	$OpenBSD: list.h,v 1.4 2021/10/01 04:36:38 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_rotate_to_front(struct list_head *list, struct list_head *head)
133 {
134 	list_del(head);
135 	list_add_tail(head, list);
136 }
137 
138 static inline void
139 list_bulk_move_tail(struct list_head *head, struct list_head *first,
140     struct list_head *last)
141 {
142 	first->prev->next = last->next;
143 	last->next->prev = first->prev;
144 	head->prev->next = first;
145 	first->prev = head->prev;
146 	last->next = head;
147 	head->prev = last;
148 }
149 
150 static inline void
151 list_del_init(struct list_head *entry) {
152 	(entry)->next->prev = (entry)->prev;
153 	(entry)->prev->next = (entry)->next;
154 	INIT_LIST_HEAD(entry);
155 }
156 
157 #define list_next_entry(pos, member)				\
158 	list_entry(((pos)->member.next), typeof(*(pos)), member)
159 
160 #define list_prev_entry(pos, member)				\
161 	list_entry(((pos)->member.prev), typeof(*(pos)), member)
162 
163 #define list_safe_reset_next(pos, n, member)			\
164 	n = list_next_entry(pos, member)
165 
166 #define list_for_each(entry, head)				\
167     for (entry = (head)->next; entry != head; entry = (entry)->next)
168 
169 #define list_for_each_prev(entry, head) \
170         for (entry = (head)->prev; entry != (head); \
171                 entry = entry->prev)
172 
173 #define list_for_each_safe(entry, temp, head)			\
174     for (entry = (head)->next, temp = (entry)->next;		\
175 	entry != head; 						\
176 	entry = temp, temp = entry->next)
177 
178 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
179 	for (pos = list_entry((head)->prev, __typeof(*pos), member),	\
180 	    n = list_entry((pos)->member.prev, __typeof(*pos), member);	\
181 	    &(pos)->member != (head);					\
182 	    pos = n, n = list_entry(n->member.prev, __typeof(*n), member))
183 
184 #define list_for_each_entry_safe_from(pos, n, head, member) 		\
185 	for (n = list_entry(pos->member.next, __typeof(*pos), member);	\
186 	     &pos->member != (head);					\
187 	     pos = n, n = list_entry(n->member.next, __typeof(*n), member))
188 
189 #define list_for_each_entry(pos, head, member)				\
190     for (pos = list_entry((head)->next, __typeof(*pos), member);	\
191 	&pos->member != (head);					 	\
192 	pos = list_entry(pos->member.next, __typeof(*pos), member))
193 
194 #define list_for_each_entry_from(pos, head, member)			\
195     for (;								\
196 	&pos->member != (head);					 	\
197 	pos = list_entry(pos->member.next, __typeof(*pos), member))
198 
199 #define list_for_each_entry_reverse(pos, head, member)			\
200     for (pos = list_entry((head)->prev, __typeof(*pos), member);	\
201 	&pos->member != (head);					 	\
202 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
203 
204 #define list_for_each_entry_from_reverse(pos, head, member)		\
205     for (;								\
206 	&pos->member != (head);					 	\
207 	pos = list_entry(pos->member.prev, __typeof(*pos), member))
208 
209 #define list_for_each_entry_continue(pos, head, member)				\
210     for (pos = list_entry((pos)->member.next, __typeof(*pos), member);	\
211 	&pos->member != (head);					 	\
212 	pos = list_entry(pos->member.next, __typeof(*pos), member))
213 
214 #define list_for_each_entry_continue_reverse(pos, head, member)         \
215         for (pos = list_entry(pos->member.prev, __typeof(*pos), member);  \
216              &pos->member != (head);    				\
217              pos = list_entry(pos->member.prev, __typeof(*pos), member))
218 
219 /**
220  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
221  * @pos:        the type * to use as a loop cursor.
222  * @n:          another type * to use as temporary storage
223  * @head:       the head for your list.
224  * @member:     the name of the list_struct within the struct.
225  */
226 #define list_for_each_entry_safe(pos, n, head, member)			\
227 	for (pos = list_entry((head)->next, __typeof(*pos), member),	\
228 	    n = list_entry(pos->member.next, __typeof(*pos), member);	\
229 	    &pos->member != (head);					\
230 	    pos = n, n = list_entry(n->member.next, __typeof(*n), member))
231 
232 #define list_first_entry(ptr, type, member) \
233 	list_entry((ptr)->next, type, member)
234 
235 #define list_first_entry_or_null(ptr, type, member) \
236 	(list_empty(ptr) ? NULL : list_first_entry(ptr, type, member))
237 
238 #define list_last_entry(ptr, type, member) \
239 	list_entry((ptr)->prev, type, member)
240 
241 static inline void
242 __list_splice(const struct list_head *list, struct list_head *prev,
243     struct list_head *next)
244 {
245 	struct list_head *first = list->next;
246 	struct list_head *last = list->prev;
247 
248 	first->prev = prev;
249 	prev->next = first;
250 
251 	last->next = next;
252 	next->prev = last;
253 }
254 
255 static inline void
256 list_splice(const struct list_head *list, struct list_head *head)
257 {
258 	if (list_empty(list))
259 		return;
260 
261 	__list_splice(list, head, head->next);
262 }
263 
264 static inline void
265 list_splice_init(struct list_head *list, struct list_head *head)
266 {
267 	if (list_empty(list))
268 		return;
269 
270 	__list_splice(list, head, head->next);
271 	INIT_LIST_HEAD(list);
272 }
273 
274 static inline void
275 list_splice_tail(const struct list_head *list, struct list_head *head)
276 {
277 	if (list_empty(list))
278 		return;
279 
280 	__list_splice(list, head->prev, head);
281 }
282 
283 static inline void
284 list_splice_tail_init(struct list_head *list, struct list_head *head)
285 {
286 	if (list_empty(list))
287 		return;
288 
289 	__list_splice(list, head->prev, head);
290 	INIT_LIST_HEAD(list);
291 }
292 
293 void	list_sort(void *, struct list_head *,
294 	    int (*)(void *, const struct list_head *, const struct list_head *));
295 
296 #define hlist_entry(ptr, type, member) \
297 	((ptr) ? container_of(ptr, type, member) : NULL)
298 
299 static inline void
300 INIT_HLIST_HEAD(struct hlist_head *head) {
301 	head->first = NULL;
302 }
303 
304 static inline int
305 hlist_empty(const struct hlist_head *head) {
306 	return head->first == NULL;
307 }
308 
309 static inline void
310 hlist_add_head(struct hlist_node *new, struct hlist_head *head)
311 {
312 	if ((new->next = head->first) != NULL)
313 		head->first->prev = &new->next;
314 	head->first = new;
315 	new->prev = &head->first;
316 }
317 
318 static inline void
319 hlist_del_init(struct hlist_node *node)
320 {
321 	if (node->next != NULL)
322 		node->next->prev = node->prev;
323 	*(node->prev) = node->next;
324 	node->next = NULL;
325 	node->prev = NULL;
326 }
327 
328 #define hlist_for_each(pos, head) \
329 	for (pos = (head)->first; pos != NULL; pos = pos->next)
330 
331 #define hlist_for_each_entry(pos, head, member)				\
332 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
333 	     pos != NULL;						\
334 	     pos = hlist_entry((pos)->member.next, __typeof(*pos), member))
335 
336 #define hlist_for_each_entry_safe(pos, n, head, member)			\
337 	for (pos = hlist_entry((head)->first, __typeof(*pos), member);	\
338 	     pos != NULL && (n = pos->member.next, 1);			\
339 	     pos = hlist_entry(n, __typeof(*pos), member))
340 
341 #endif /* _DRM_LINUX_LIST_H_ */
342