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