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 __HI_LIST_H__
17 #define __HI_LIST_H__
18
19 #ifndef _LINUX_LIST_H
20
21 #ifdef __KERNEL__
22
23 #include <linux/types.h>
24 #else
25
26 #include <stdint.h>
27 #endif
28
29 #define INIT_LIST_HEAD(ptr) \
30 do { \
31 (ptr)->next = (ptr); \
32 (ptr)->prev = (ptr); \
33 } while (0)
34
35 #define LIST_HEAD_INIT(name) { &(name), &(name) }
36
37 struct list_head {
38 struct list_head *next, *prev;
39 };
40
__list_add(struct list_head * _new,struct list_head * prev,struct list_head * next)41 static inline void __list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
42 {
43 next->prev = _new;
44 _new->next = next;
45 _new->prev = prev;
46 prev->next = _new;
47 }
48
list_add(struct list_head * _new,struct list_head * head)49 static inline void list_add(struct list_head *_new, struct list_head *head)
50 {
51 __list_add(_new, head, head->next);
52 }
53
list_add_tail(struct list_head * _new,struct list_head * head)54 static inline void list_add_tail(struct list_head *_new, struct list_head *head)
55 {
56 __list_add(_new, head->prev, head);
57 }
58
__list_del(struct list_head * prev,struct list_head * next)59 static inline void __list_del(struct list_head *prev, struct list_head *next)
60 {
61 next->prev = prev;
62 prev->next = next;
63 }
64
list_del(struct list_head * entry)65 static inline void list_del(struct list_head *entry)
66 {
67 __list_del(entry->prev, entry->next);
68 }
69
list_del_init(struct list_head * entry)70 static inline void list_del_init(struct list_head *entry)
71 {
72 __list_del(entry->prev, entry->next);
73 INIT_LIST_HEAD(entry);
74 }
75
list_move(struct list_head * list,struct list_head * head)76 static inline void list_move(struct list_head *list, struct list_head *head)
77 {
78 __list_del(list->prev, list->next);
79 list_add(list, head);
80 }
81
list_move_tail(struct list_head * list,struct list_head * head)82 static inline void list_move_tail(struct list_head *list,
83 struct list_head *head)
84 {
85 __list_del(list->prev, list->next);
86 list_add_tail(list, head);
87 }
88
list_empty(struct list_head * head)89 static inline int list_empty(struct list_head *head)
90 {
91 return head->next == head;
92 }
93
__list_splice(struct list_head * list,struct list_head * head)94 static inline void __list_splice(struct list_head *list,
95 struct list_head *head)
96 {
97 struct list_head *first = list->next;
98 struct list_head *last = list->prev;
99 struct list_head *at = head->next;
100
101 first->prev = head;
102 head->next = first;
103
104 last->next = at;
105 at->prev = last;
106 }
107
list_splice(struct list_head * list,struct list_head * head)108 static inline void list_splice(struct list_head *list, struct list_head *head)
109 {
110 if (!list_empty(list)) {
111 __list_splice(list, head);
112 }
113 }
114
list_splice_init(struct list_head * list,struct list_head * head)115 static inline void list_splice_init(struct list_head *list, struct list_head *head)
116 {
117 if (!list_empty(list)) {
118 __list_splice(list, head);
119 INIT_LIST_HEAD(list);
120 }
121 }
122
123 #define list_entry(ptr, type, member) \
124 ((type *)((uintptr_t)(ptr) - ((unsigned long)(&((type *)1)->member) - 1)))
125
126 #define list_for_each(pos, head) \
127 for (pos = (head)->next; pos != (head); pos = pos->next)
128
129 #define list_for_each_safe(pos, n, head) \
130 for (pos = (head)->next, n = pos->next; pos != (head); \
131 pos = n, n = pos->next)
132
133 #define get_first_item(attached, type, member) \
134 ((type *)((char *)((attached)->next) - (unsigned long)(&((type *)0)->member)))
135
136 #endif
137
138 #endif
139