M4521_BSP V3.02.000
The Board Support Package for M4521
usbh_list.h
Go to the documentation of this file.
1#ifndef _LIST_H_
2#define _LIST_H_
3
5/*
6 * Simple doubly linked list implementation.
7 *
8 * Some of the internal functions ("__xxx") are useful when
9 * manipulating whole lists rather than single entries, as
10 * sometimes we already know the next/prev entries and we can
11 * generate better code by using them directly rather than
12 * using the generic single-entry routines.
13 */
14
15typedef struct list_head
16{
17 struct list_head *next, *prev;
18} USB_LIST_T;
19
20#define LIST_HEAD_INIT(name) { &(name), &(name) }
21
22#define LIST_HEAD(name) \
23 USB_LIST_T name = LIST_HEAD_INIT(name)
24
25#define INIT_LIST_HEAD(ptr) do { \
26 (ptr)->next = (ptr); (ptr)->prev = (ptr); \
27} while (0)
28
29/*
30 * Insert a new entry between two known consecutive entries.
31 *
32 * This is only for internal list manipulation where we know
33 * the prev/next entries already!
34 */
35
36static __inline void __list_add(USB_LIST_T * new,
37 USB_LIST_T * prev,
38 USB_LIST_T * next)
39{
40 next->prev = new;
41 new->next = next;
42 new->prev = prev;
43 prev->next = new;
44}
45
54static __inline void list_add(USB_LIST_T *new, USB_LIST_T *head)
55{
56 __list_add(new, head, head->next);
57}
58
67static __inline void list_add_tail(USB_LIST_T *new, USB_LIST_T *head)
68{
69 __list_add(new, head->prev, head);
70}
71
72/*
73 * Delete a list entry by making the prev/next entries
74 * point to each other.
75 *
76 * This is only for internal list manipulation where we know
77 * the prev/next entries already!
78 */
79static __inline void __list_del(USB_LIST_T * prev,
80 USB_LIST_T * next)
81{
82 next->prev = prev;
83 prev->next = next;
84}
85
91static __inline void list_del(USB_LIST_T *entry)
92{
93 __list_del(entry->prev, entry->next);
94}
95
100static __inline void list_del_init(USB_LIST_T *entry)
101{
102 __list_del(entry->prev, entry->next);
103 INIT_LIST_HEAD(entry);
104}
105
110static __inline int list_empty(USB_LIST_T *head)
111{
112 return head->next == head;
113}
114
120static __inline void list_splice(USB_LIST_T *list, USB_LIST_T *head)
121{
122 USB_LIST_T *first = list->next;
123
124 if(first != list)
125 {
126 USB_LIST_T *last = list->prev;
127 USB_LIST_T *at = head->next;
128
129 first->prev = head;
130 head->next = first;
131
132 last->next = at;
133 at->prev = last;
134 }
135}
136
143#define list_entry(ptr, type, member) \
144 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
145
151#define list_for_each(pos, head) \
152 for (pos = (head)->next; pos != (head); pos = pos->next)
153
154
161#define list_for_each_safe(pos, n, head) \
162 for (pos = (head)->next, n = pos->next; pos != (head); \
163 pos = n, n = pos->next)
164
165
166static __inline void __list_splice(struct list_head *list, struct list_head *head)
167{
168 struct list_head *first = list->next;
169 struct list_head *last = list->prev;
170 struct list_head *at = head->next;
171
172 first->prev = head;
173 head->next = first;
174
175 last->next = at;
176 at->prev = last;
177}
178
179
180static __inline void list_move_tail(struct list_head *list, struct list_head *head)
181{
182 __list_del(list->prev, list->next);
183 list_add_tail(list, head);
184}
185
186
192static __inline void list_move(struct list_head *list, struct list_head *head)
193{
194 __list_del(list->prev, list->next);
195 list_add(list, head);
196}
197
199
200#endif /* _LIST_H_ */