1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef _OSAL_LIST_H
17 #define _OSAL_LIST_H
18 
19 #define OSAL_NULL   0
20 #define osal_unused(x)           ((void)(x))
21 
22 /*
23  * Simple doubly linked list implementation.
24  *
25  * Some of the internal functions ("__xxx") are useful when
26  * manipulating whole lists rather than single entries, as
27  * sometimes we already know the next/prev entries and we can
28  * generate better code by using them directly rather than
29  * using the generic single-entry routines.
30  */
31 struct osal_list_head {
32     struct osal_list_head *next, *prev;
33 };
34 #define OSAL_LIST_HEAD_INIT(name) \
35     {                             \
36         &(name), &(name)          \
37     }
38 
39 #define OSAL_LIST_HEAD(name) \
40     struct osal_list_head name = OSAL_LIST_HEAD_INIT(name)
41 
OSAL_INIT_LIST_HEAD(struct osal_list_head *list)42 static inline void OSAL_INIT_LIST_HEAD(struct osal_list_head *list)
43 {
44     list->next = list;
45     list->prev = list;
46 }
47 
48 /*
49  * Insert a new entry between two known consecutive entries.
50  *
51  * This is only for internal list manipulation where we know
52  * the prev/next entries already!
53  */
osal___list_add(struct osal_list_head *new, struct osal_list_head *prev, struct osal_list_head *next)54 static inline void osal___list_add(struct osal_list_head *new,
55                                    struct osal_list_head *prev,
56                                    struct osal_list_head *next)
57 {
58     next->prev = new;
59     new->next = next;
60     new->prev = prev;
61     prev->next = new;
62 }
63 
64 /*
65  * list_add - add a new entry
66  * @new: new entry to be added
67  * @head: list head to add it after
68  *
69  * Insert a new entry after the specified head.
70  * This is good for implementing stacks.
71  */
osal_list_add(struct osal_list_head *new, struct osal_list_head *head)72 static inline void osal_list_add(struct osal_list_head *new, struct osal_list_head *head)
73 {
74     osal___list_add(new, head, head->next);
75 }
76 
77 /*
78  * list_add_tail - add a new entry
79  * @new: new entry to be added
80  * @head: list head to add it before
81  *
82  * Insert a new entry before the specified head.
83  * This is useful for implementing queues.
84  */
osal_list_add_tail(struct osal_list_head *new, struct osal_list_head *head)85 static inline void osal_list_add_tail(struct osal_list_head *new, struct osal_list_head *head)
86 {
87     osal___list_add(new, head->prev, head);
88 }
89 
90 /*
91  * Delete a list entry by making the prev/next entries
92  * point to each other.
93  *
94  * This is only for internal list manipulation where we know
95  * the prev/next entries already!
96  */
osal___list_del(struct osal_list_head *prev, struct osal_list_head *next)97 static inline void osal___list_del(struct osal_list_head *prev, struct osal_list_head *next)
98 {
99     next->prev = prev;
100     prev->next = next;
101 }
102 
103 /*
104  * list_del - deletes entry from list.
105  * @entry: the element to delete from the list.
106  * Note: list_empty() on entry does not return true after this, the entry is
107  * in an undefined state.
108  */
osal___list_del_entry(struct osal_list_head *entry)109 static inline void osal___list_del_entry(struct osal_list_head *entry)
110 {
111     osal___list_del(entry->prev, entry->next);
112 }
113 
114 #define OSAL_LIST_POISON1    ((void *)0x00100100)
115 #define OSAL_LIST_POISON2    ((void *)0x00200200)
116 
osal_list_del(struct osal_list_head *entry)117 static inline void osal_list_del(struct osal_list_head *entry)
118 {
119     osal___list_del(entry->prev, entry->next);
120     entry->next = OSAL_LIST_POISON1;
121     entry->prev = OSAL_LIST_POISON2;
122 }
123 
124 /*
125  * list_replace - replace old entry by new one
126  * @old : the element to be replaced
127  * @new : the new element to insert
128  *
129  * If @old was empty, it will be overwritten.
130  */
osal_list_replace(struct osal_list_head *old, struct osal_list_head *new)131 static inline void osal_list_replace(struct osal_list_head *old,
132                                      struct osal_list_head *new)
133 {
134     new->next = old->next;
135     new->next->prev = new;
136     new->prev = old->prev;
137     new->prev->next = new;
138 }
139 
osal_list_replace_init(struct osal_list_head *old, struct osal_list_head *new)140 static inline void osal_list_replace_init(struct osal_list_head *old,
141                                           struct osal_list_head *new)
142 {
143     osal_list_replace(old, new);
144     OSAL_INIT_LIST_HEAD(old);
145 }
146 
147 /*
148  * list_del_init - deletes entry from list and reinitialize it.
149  * @entry: the element to delete from the list.
150  */
osal_list_del_init(struct osal_list_head *entry)151 static inline void osal_list_del_init(struct osal_list_head *entry)
152 {
153     osal___list_del_entry(entry);
154     OSAL_INIT_LIST_HEAD(entry);
155 }
156 
157 /*
158  * list_move - delete from one list and add as another head
159  * @list: the entry to move
160  * @head: the head that will precede our entry
161  */
osal_list_move(struct osal_list_head *list, struct osal_list_head *head)162 static inline void osal_list_move(struct osal_list_head *list, struct osal_list_head *head)
163 {
164     osal___list_del_entry(list);
165     osal_list_add(list, head);
166 }
167 
168 /*
169  * list_move_tail - delete from one list and add as another tail
170  * @list: the entry to move
171  * @head: the head that will follow our entry
172  */
osal_list_move_tail(struct osal_list_head *list, struct osal_list_head *head)173 static inline void osal_list_move_tail(struct osal_list_head *list,
174                                        struct osal_list_head *head)
175 {
176     osal___list_del_entry(list);
177     osal_list_add_tail(list, head);
178 }
179 
180 /*
181  * list_is_last - tests whether @list is the last entry in list @head
182  * @list: the entry to test
183  * @head: the head of the list
184  */
osal_list_is_last(const struct osal_list_head *list, const struct osal_list_head *head)185 static inline int osal_list_is_last(const struct osal_list_head *list,
186                                     const struct osal_list_head *head)
187 {
188     return list->next == head;
189 }
190 
191 /*
192  * list_empty - tests whether a list is empty
193  * @head: the list to test.
194  */
osal_list_empty(const struct osal_list_head *head)195 static inline int osal_list_empty(const struct osal_list_head *head)
196 {
197     return head->next == head;
198 }
199 
200 /*
201  * list_empty_careful - tests whether a list is empty and not being modified
202  * @head: the list to test
203  *
204  * Description:
205  * tests whether a list is empty _and_ checks that no other CPU might be
206  * in the process of modifying either member (next or prev)
207  *
208  * NOTE: using list_empty_careful() without synchronization
209  * can only be safe if the only activity that can happen
210  * to the list entry is list_del_init(). Eg. it cannot be used
211  * if another CPU could re-list_add() it.
212  */
osal_list_empty_careful(const struct osal_list_head *head)213 static inline int osal_list_empty_careful(const struct osal_list_head *head)
214 {
215     struct osal_list_head *next = head->next;
216     return (next == head) && (next == head->prev);
217 }
218 
219 /*
220  * list_rotate_left - rotate the list to the left
221  * @head: the head of the list
222  */
osal_list_rotate_left(struct osal_list_head *head)223 static inline void osal_list_rotate_left(struct osal_list_head *head)
224 {
225     struct osal_list_head *first = OSAL_NULL;
226 
227     if (!osal_list_empty(head)) {
228         first = head->next;
229         osal_list_move_tail(first, head);
230     }
231 }
232 
233 /*
234  * list_is_singular - tests whether a list has just one entry.
235  * @head: the list to test.
236  */
osal_list_is_singular(const struct osal_list_head *head)237 static inline int osal_list_is_singular(const struct osal_list_head *head)
238 {
239     return !osal_list_empty(head) && (head->next == head->prev);
240 }
241 
osal___list_cut_position(struct osal_list_head *list, struct osal_list_head *head, struct osal_list_head *entry)242 static inline void osal___list_cut_position(struct osal_list_head *list,
243                                             struct osal_list_head *head, struct osal_list_head *entry)
244 {
245     struct osal_list_head *new_first = entry->next;
246     list->next = head->next;
247     list->next->prev = list;
248     list->prev = entry;
249     entry->next = list;
250     head->next = new_first;
251     new_first->prev = head;
252 }
253 
254 /*
255  * list_cut_position - cut a list into two
256  * @list: a new list to add all removed entries
257  * @head: a list with entries
258  * @entry: an entry within head, could be the head itself
259  *    and if so we won't cut the list
260  *
261  * This helper moves the initial part of @head, up to and
262  * including @entry, from @head to @list. You should
263  * pass on @entry an element you know is on @head. @list
264  * should be an empty list or a list you do not care about
265  * losing its data.
266  *
267  */
osal_list_cut_position(struct osal_list_head *list, struct osal_list_head *head, struct osal_list_head *entry)268 static inline void osal_list_cut_position(struct osal_list_head *list,
269                                           struct osal_list_head *head, struct osal_list_head *entry)
270 {
271     if (osal_list_empty(head)) {
272         return;
273     }
274     if (osal_list_is_singular(head) &&
275         ((head->next != entry) && (head != entry))) {
276         return;
277     }
278     if (entry == head) {
279         OSAL_INIT_LIST_HEAD(list);
280     } else {
281         osal___list_cut_position(list, head, entry);
282     }
283 }
284 
osal___list_splice(const struct osal_list_head *list, struct osal_list_head *prev, struct osal_list_head *next)285 static inline void osal___list_splice(const struct osal_list_head *list,
286                                       struct osal_list_head *prev,
287                                       struct osal_list_head *next)
288 {
289     struct osal_list_head *first = list->next;
290     struct osal_list_head *last = list->prev;
291 
292     first->prev = prev;
293     prev->next = first;
294 
295     last->next = next;
296     next->prev = last;
297 }
298 
299 /*
300  * list_splice - join two lists, this is designed for stacks
301  * @list: the new list to add.
302  * @head: the place to add it in the first list.
303  */
osal_list_splice(const struct osal_list_head *list, struct osal_list_head *head)304 static inline void osal_list_splice(const struct osal_list_head *list,
305                                     struct osal_list_head *head)
306 {
307     if (!osal_list_empty(list)) {
308         osal___list_splice(list, head, head->next);
309     }
310 }
311 
312 /*
313  * list_splice_tail - join two lists, each list being a queue
314  * @list: the new list to add.
315  * @head: the place to add it in the first list.
316  */
osal_list_splice_tail(struct osal_list_head *list, struct osal_list_head *head)317 static inline void osal_list_splice_tail(struct osal_list_head *list,
318                                          struct osal_list_head *head)
319 {
320     if (!osal_list_empty(list)) {
321         osal___list_splice(list, head->prev, head);
322     }
323 }
324 
325 /*
326  * list_splice_init - join two lists and reinitialise the emptied list.
327  * @list: the new list to add.
328  * @head: the place to add it in the first list.
329  *
330  * The list at @list is reinitialised
331  */
osal_list_splice_init(struct osal_list_head *list, struct osal_list_head *head)332 static inline void osal_list_splice_init(struct osal_list_head *list,
333                                          struct osal_list_head *head)
334 {
335     if (!osal_list_empty(list)) {
336         osal___list_splice(list, head, head->next);
337         OSAL_INIT_LIST_HEAD(list);
338     }
339 }
340 
341 /*
342  * list_splice_tail_init - join two lists and reinitialise the emptied list
343  * @list: the new list to add.
344  * @head: the place to add it in the first list.
345  *
346  * Each of the lists is a queue.
347  * The list at @list is reinitialised
348  */
osal_list_splice_tail_init(struct osal_list_head *list, struct osal_list_head *head)349 static inline void osal_list_splice_tail_init(struct osal_list_head *list,
350                                               struct osal_list_head *head)
351 {
352     if (!osal_list_empty(list)) {
353         osal___list_splice(list, head->prev, head);
354         OSAL_INIT_LIST_HEAD(list);
355     }
356 }
357 
358 #undef osal_offsetof
359 #ifdef __compiler_offsetof
360 #define osal_offsetof(TYPE, MEMBER)  (__compiler_offsetof(TYPE, MEMBER))
361 #else
362 #define osal_offsetof(TYPE, MEMBER) ((int)(unsigned long)&((TYPE *)0)->MEMBER)
363 #endif
364 
365 #define osal_container_of(ptr, type, member) ({                \
366     __typeof__(((type *)0)->member) *__mptr = (ptr);    \
367     (type *)((char *)__mptr - (osal_offsetof(type, member))); })
368 
369 /*
370  * list_entry - get the struct for this entry
371  * @ptr:    the &struct list_head pointer.
372  * @type:    the type of the struct this is embedded in.
373  * @member:    the name of the list_struct within the struct.
374  */
375 #define osal_list_entry(ptr, type, member) \
376     osal_container_of(ptr, type, member)
377 
378 /*
379  * list_first_entry - get the first element from a list
380  * @ptr:    the list head to take the element from.
381  * @type:    the type of the struct this is embedded in.
382  * @member:    the name of the list_struct within the struct.
383  *
384  * Note, that list is expected to be not empty.
385  */
386 #define osal_list_first_entry(ptr, type, member) \
387     osal_list_entry((ptr)->next, type, member)
388 
389 /**
390  * list_for_each    -    iterate over a list
391  * @pos:    the &struct list_head to use as a loop cursor.
392  * @head:    the head for your list.
393  */
394 #define osal_list_for_each(pos, head) \
395     for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
396 
397 /*
398  * __list_for_each    -    iterate over a list
399  * @pos:    the &struct list_head to use as a loop cursor.
400  * @head:    the head for your list.
401  *
402  * This variant doesn't differ from list_for_each() any more.
403  * We don't do prefetching in either case.
404  */
405 #define osal___list_for_each(pos, head) \
406     for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
407 
408 /*
409  * list_for_each_prev    -    iterate over a list backwards
410  * @pos:    the &struct list_head to use as a loop cursor.
411  * @head:    the head for your list.
412  */
413 #define osal_list_for_each_prev(pos, head) \
414     for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
415 
416 /*
417  * list_for_each_safe - iterate over a list safe against removal of list entry
418  * @pos:    the &struct list_head to use as a loop cursor.
419  * @n:        another &struct list_head to use as temporary storage
420  * @head:    the head for your list.
421  */
422 #define osal_list_for_each_safe(pos, n, head)              \
423     for ((pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
424          (pos) = (n), (n) = (pos)->next)
425 
426 /*
427  * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
428  * @pos:    the &struct list_head to use as a loop cursor.
429  * @n:        another &struct list_head to use as temporary storage
430  * @head:    the head for your list.
431  */
432 #define osal_list_for_each_prev_safe(pos, n, head) \
433     for ((pos) = (head)->prev, (n) = (pos)->prev;        \
434          (pos) != (head);                            \
435          (pos) = (n), (n) = (pos)->prev)
436 
437 /*
438  * list_for_each_entry    -    iterate over list of given type
439  * @pos:    the type * to use as a loop cursor.
440  * @head:    the head for your list.
441  * @member:    the name of the list_struct within the struct.
442  */
443 #define osal_list_for_each_entry(pos, head, member)                     \
444     for ((pos) = osal_list_entry((head)->next, __typeof__(*(pos)), member); \
445          &(pos)->member != (head);                                        \
446          (pos) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member))
447 
448 /*
449  * list_for_each_entry_reverse - iterate backwards over list of given type.
450  * @pos:    the type * to use as a loop cursor.
451  * @head:    the head for your list.
452  * @member:    the name of the list_struct within the struct.
453  */
454 #define osal_list_for_each_entry_reverse(pos, head, member)             \
455     for ((pos) = osal_list_entry((head)->prev, __typeof__(*(pos)), member); \
456          &(pos)->member != (head);                                        \
457          (pos) = osal_list_entry((pos)->member.prev, __typeof__(*(pos)), member))
458 
459 /*
460  * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
461  * @pos:    the type * to use as a start point
462  * @head:    the head of the list
463  * @member:    the name of the list_struct within the struct.
464  *
465  * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
466  */
467 #define osal_list_prepare_entry(pos, head, member) \
468     ((pos) ? : osal_list_entry(head, __typeof__(*(pos)), member))
469 
470 /**
471  * list_for_each_entry_continue - continue iteration over list of given type
472  * @pos:    the type * to use as a loop cursor.
473  * @head:    the head for your list.
474  * @member:    the name of the list_struct within the struct.
475  *
476  * Continue to iterate over list of given type, continuing after
477  * the current position.
478  */
479 #define osal_list_for_each_entry_continue(pos, head, member)                \
480     for ((pos) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member); \
481          &(pos)->member != (head);                                            \
482          (pos) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member))
483 
484 /*
485  * list_for_each_entry_continue_reverse - iterate backwards from the given point
486  * @pos:    the type * to use as a loop cursor.
487  * @head:    the head for your list.
488  * @member:    the name of the list_struct within the struct.
489  *
490  * Start to iterate over list of given type backwards, continuing after
491  * the current position.
492  */
493 #define osal_list_for_each_entry_continue_reverse(pos, head, member)        \
494     for ((pos) = osal_list_entry((pos)->member.prev, __typeof__(*(pos)), member); \
495          &(pos)->member != (head);                                            \
496          (pos) = osal_list_entry((pos)->member.prev, __typeof__(*(pos)), member))
497 
498 /*
499  * list_for_each_entry_from - iterate over list of given type from the current point
500  * @pos:    the type * to use as a loop cursor.
501  * @head:    the head for your list.
502  * @member:    the name of the list_struct within the struct.
503  *
504  * Iterate over list of given type, continuing from current position.
505  */
506 #define osal_list_for_each_entry_from(pos, head, member) \
507     for (; &(pos)->member != (head);                       \
508          (pos) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member))
509 
510 /*
511  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
512  * @pos:    the type * to use as a loop cursor.
513  * @n:        another type * to use as temporary storage
514  * @head:    the head for your list.
515  * @member:    the name of the list_struct within the struct.
516  */
517 #define osal_list_for_each_entry_safe(pos, n, head, member)              \
518     for ((pos) = osal_list_entry((head)->next, __typeof__(*(pos)), member),  \
519         (n) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member); \
520          &(pos)->member != (head);                                         \
521          (pos) = (n), (n) = osal_list_entry((n)->member.next, __typeof__(*(n)), member))
522 
523 /*
524  * list_for_each_entry_safe_continue - continue list iteration safe against removal
525  * @pos:    the type * to use as a loop cursor.
526  * @n:        another type * to use as temporary storage
527  * @head:    the head for your list.
528  * @member:    the name of the list_struct within the struct.
529  *
530  * Iterate over list of given type, continuing after current point,
531  * safe against removal of list entry.
532  */
533 #define osal_list_for_each_entry_safe_continue(pos, n, head, member)        \
534     for ((pos) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member), \
535         (n) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member);    \
536          &(pos)->member != (head);                                            \
537          (pos) = (n), (n) = osal_list_entry((n)->member.next, __typeof__(*(n)), member))
538 
539 /*
540  * list_for_each_entry_safe_from - iterate over list from current point safe against removal
541  * @pos:    the type * to use as a loop cursor.
542  * @n:        another type * to use as temporary storage
543  * @head:    the head for your list.
544  * @member:    the name of the list_struct within the struct.
545  *
546  * Iterate over list of given type from current point, safe against
547  * removal of list entry.
548  */
549 #define osal_list_for_each_entry_safe_from(pos, n, head, member)          \
550     for ((n) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member); \
551          &(pos)->member != (head);                                          \
552          (pos) = (n), (n) = osal_list_entry((n)->member.next, __typeof__(*(n)), member))
553 
554 /*
555  * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
556  * @pos:    the type * to use as a loop cursor.
557  * @n:        another type * to use as temporary storage
558  * @head:    the head for your list.
559  * @member:    the name of the list_struct within the struct.
560  *
561  * Iterate backwards over list of given type, safe against removal
562  * of list entry.
563  */
564 #define osal_list_for_each_entry_safe_reverse(pos, n, head, member)      \
565     for ((pos) = osal_list_entry((head)->prev, __typeof__(*(pos)), member),  \
566         (n) = osal_list_entry((pos)->member.prev, __typeof__(*(pos)), member); \
567          &(pos)->member != (head);                                         \
568          (pos) = (n), (n) = osal_list_entry((n)->member.prev, __typeof__(*(n)), member))
569 
570 /*
571  * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
572  * @pos:    the loop cursor used in the list_for_each_entry_safe loop
573  * @n:        temporary storage used in list_for_each_entry_safe
574  * @member:    the name of the list_struct within the struct.
575  *
576  * list_safe_reset_next is not safe to use in general if the list may be
577  * modified concurrently (eg. the lock is dropped in the loop body). An
578  * exception to this is if the cursor element (pos) is pinned in the list,
579  * and list_safe_reset_next is called after re-taking the lock and before
580  * completing the current iteration of the loop body.
581  */
582 #define osal_list_safe_reset_next(pos, n, member) \
583     (n) = osal_list_entry((pos)->member.next, __typeof__(*(pos)), member)
584 
585 /*
586  * Double linked lists with a single pointer list head.
587  * Mostly useful for hash tables where the two pointer list head is
588  * too wasteful.
589  * You lose the ability to access the tail in O(1).
590  */
591 struct osal_hlist_node {
592     struct osal_hlist_node *next, **pprev;
593 };
594 struct osal_hlist_head {
595     struct osal_hlist_node *first;
596 };
597 
598 #define OSAL_HLIST_HEAD_INIT \
599     {                        \
600         .first = OSAL_NULL   \
601     }
602 #define OSAL_HLIST_HEAD(name) struct osal_hlist_head name = { .first = OSAL_NULL }
603 #define INIT_OSAL_HLIST_HEAD(ptr) ((ptr)->first = OSAL_NULL)
INIT_OSAL_HLIST_NODE(struct osal_hlist_node *h)604 static inline void INIT_OSAL_HLIST_NODE(struct osal_hlist_node *h)
605 {
606     h->next = OSAL_NULL;
607     h->pprev = OSAL_NULL;
608 }
609 
osal_hlist_unhashed(const struct osal_hlist_node *h)610 static inline int osal_hlist_unhashed(const struct osal_hlist_node *h)
611 {
612     return !h->pprev;
613 }
614 
osal_hlist_empty(const struct osal_hlist_head *h)615 static inline int osal_hlist_empty(const struct osal_hlist_head *h)
616 {
617     return !h->first;
618 }
619 
osal___hlist_del(struct osal_hlist_node *n)620 static inline void osal___hlist_del(struct osal_hlist_node *n)
621 {
622     struct osal_hlist_node *next = n->next;
623     struct osal_hlist_node **pprev = n->pprev;
624     *pprev = next;
625     if (next != OSAL_NULL) {
626         next->pprev = pprev;
627     }
628 }
629 
osal_hlist_del(struct osal_hlist_node *n)630 static inline void osal_hlist_del(struct osal_hlist_node *n)
631 {
632     osal___hlist_del(n);
633     n->next = OSAL_LIST_POISON1;
634     n->pprev = OSAL_LIST_POISON2;
635 }
636 
osal_hlist_del_init(struct osal_hlist_node *n)637 static inline void osal_hlist_del_init(struct osal_hlist_node *n)
638 {
639     if (!osal_hlist_unhashed(n)) {
640         osal___hlist_del(n);
641         INIT_OSAL_HLIST_NODE(n);
642     }
643 }
644 
osal_hlist_add_head(struct osal_hlist_node *n, struct osal_hlist_head *h)645 static inline void osal_hlist_add_head(struct osal_hlist_node *n, struct osal_hlist_head *h)
646 {
647     struct osal_hlist_node *first = h->first;
648     n->next = first;
649     if (first != OSAL_NULL) {
650         first->pprev = &n->next;
651     }
652     h->first = n;
653     n->pprev = &h->first;
654 }
655 
656 /* next must be != NULL */
osal_hlist_add_before(struct osal_hlist_node *n, struct osal_hlist_node *next)657 static inline void osal_hlist_add_before(struct osal_hlist_node *n,
658                                          struct osal_hlist_node *next)
659 {
660     n->pprev = next->pprev;
661     n->next = next;
662     next->pprev = &n->next;
663     *(n->pprev) = n;
664 }
665 
osal_hlist_add_after(struct osal_hlist_node *n, struct osal_hlist_node *next)666 static inline void osal_hlist_add_after(struct osal_hlist_node *n,
667                                         struct osal_hlist_node *next)
668 {
669     next->next = n->next;
670     n->next = next;
671     next->pprev = &n->next;
672 
673     if (next->next != OSAL_NULL) {
674         next->next->pprev = &next->next;
675     }
676 }
677 
678 /* after that we'll appear to be on some hlist and hlist_del will work */
osal_hlist_add_fake(struct osal_hlist_node *n)679 static inline void osal_hlist_add_fake(struct osal_hlist_node *n)
680 {
681     n->pprev = &n->next;
682 }
683 
684 /*
685  * Move a list from one list head to another. Fixup the pprev
686  * reference of the first entry if it exists.
687  */
osal_hlist_move_list(struct osal_hlist_head *old, struct osal_hlist_head *new)688 static inline void osal_hlist_move_list(struct osal_hlist_head *old,
689                                         struct osal_hlist_head *new)
690 {
691     new->first = old->first;
692     if (new->first != OSAL_NULL) {
693         new->first->pprev = &new->first;
694     }
695     old->first = OSAL_NULL;
696 }
697 
698 #define osal_hlist_entry(ptr, type, member) osal_container_of(ptr, type, member)
699 
700 #define osal_hlist_for_each(pos, head) \
701     for ((pos) = (head)->first; (pos); (pos) = (pos)->next)
702 
703 #define osal_hlist_for_each_safe(pos, n, head) \
704     for ((pos) = (head)->first; (pos) && ({ n = (pos)->next; 1; });    \
705          (pos) = (n))
706 
707 /*
708  * hlist_for_each_entry    - iterate over list of given type
709  * @tpos:    the type * to use as a loop cursor.
710  * @pos:    the &struct hlist_node to use as a loop cursor.
711  * @head:    the head for your list.
712  * @member:    the name of the hlist_node within the struct.
713  */
714 #define osal_hlist_for_each_entry(tpos, pos, head, member) \
715     for ((pos) = (head)->first;                              \
716          (pos) &&                                            \
717          ({ (tpos) = osal_hlist_entry((pos), __typeof__(*(tpos)), member); 1; });  \
718          (pos) = (pos)->next)
719 
720 /*
721  * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
722  * @tpos:    the type * to use as a loop cursor.
723  * @pos:    the &struct hlist_node to use as a loop cursor.
724  * @member:    the name of the hlist_node within the struct.
725  */
726 #define osal_hlist_for_each_entry_continue(tpos, pos, member) \
727     for ((pos) = (pos)->next;                                   \
728          (pos) &&                                               \
729          ({ (tpos) = osal_hlist_entry((pos), __typeof__(*(tpos)), member); 1; });  \
730          (pos) = (pos)->next)
731 
732 /*
733  * hlist_for_each_entry_from - iterate over a hlist continuing from current point
734  * @tpos:    the type * to use as a loop cursor.
735  * @pos:    the &struct hlist_node to use as a loop cursor.
736  * @member:    the name of the hlist_node within the struct.
737  */
738 #define osal_hlist_for_each_entry_from(tpos, pos, member) \
739     for (; (pos) &&                                         \
740            ({ (tpos) = osal_hlist_entry((pos), __typeof__(*(tpos)), member); 1; });  \
741          (pos) = (pos)->next)
742 
743 /*
744  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
745  * @tpos:    the type * to use as a loop cursor.
746  * @pos:    the &struct hlist_node to use as a loop cursor.
747  * @n:        another &struct hlist_node to use as temporary storage
748  * @head:    the head for your list.
749  * @member:    the name of the hlist_node within the struct.
750  */
751 #define osal_hlist_for_each_entry_safe(tpos, pos, n, head, member) \
752     for ((pos) = (head)->first;                                      \
753          (pos) && ({ n = (pos)->next; 1; }) &&                                           \
754          ({ (tpos) = osal_hlist_entry((pos), __typeof__(*(tpos)), member); 1; });          \
755          (pos) = (n))
756 
757 #endif
758