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