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