mkregtable.c revision 1.1.1.1.2.2 1 1.1.1.1.2.2 tls /* utility to create the register check tables
2 1.1.1.1.2.2 tls * this includes inlined list.h safe for userspace.
3 1.1.1.1.2.2 tls *
4 1.1.1.1.2.2 tls * Copyright 2009 Jerome Glisse
5 1.1.1.1.2.2 tls * Copyright 2009 Red Hat Inc.
6 1.1.1.1.2.2 tls *
7 1.1.1.1.2.2 tls * Authors:
8 1.1.1.1.2.2 tls * Jerome Glisse
9 1.1.1.1.2.2 tls * Dave Airlie
10 1.1.1.1.2.2 tls */
11 1.1.1.1.2.2 tls
12 1.1.1.1.2.2 tls #include <sys/types.h>
13 1.1.1.1.2.2 tls #include <stdlib.h>
14 1.1.1.1.2.2 tls #include <string.h>
15 1.1.1.1.2.2 tls #include <stdio.h>
16 1.1.1.1.2.2 tls #include <regex.h>
17 1.1.1.1.2.2 tls #include <libgen.h>
18 1.1.1.1.2.2 tls
19 1.1.1.1.2.2 tls #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
20 1.1.1.1.2.2 tls /**
21 1.1.1.1.2.2 tls * container_of - cast a member of a structure out to the containing structure
22 1.1.1.1.2.2 tls * @ptr: the pointer to the member.
23 1.1.1.1.2.2 tls * @type: the type of the container struct this is embedded in.
24 1.1.1.1.2.2 tls * @member: the name of the member within the struct.
25 1.1.1.1.2.2 tls *
26 1.1.1.1.2.2 tls */
27 1.1.1.1.2.2 tls #define container_of(ptr, type, member) ({ \
28 1.1.1.1.2.2 tls const typeof(((type *)0)->member)*__mptr = (ptr); \
29 1.1.1.1.2.2 tls (type *)((char *)__mptr - offsetof(type, member)); })
30 1.1.1.1.2.2 tls
31 1.1.1.1.2.2 tls /*
32 1.1.1.1.2.2 tls * Simple doubly linked list implementation.
33 1.1.1.1.2.2 tls *
34 1.1.1.1.2.2 tls * Some of the internal functions ("__xxx") are useful when
35 1.1.1.1.2.2 tls * manipulating whole lists rather than single entries, as
36 1.1.1.1.2.2 tls * sometimes we already know the next/prev entries and we can
37 1.1.1.1.2.2 tls * generate better code by using them directly rather than
38 1.1.1.1.2.2 tls * using the generic single-entry routines.
39 1.1.1.1.2.2 tls */
40 1.1.1.1.2.2 tls
41 1.1.1.1.2.2 tls struct list_head {
42 1.1.1.1.2.2 tls struct list_head *next, *prev;
43 1.1.1.1.2.2 tls };
44 1.1.1.1.2.2 tls
45 1.1.1.1.2.2 tls #define LIST_HEAD_INIT(name) { &(name), &(name) }
46 1.1.1.1.2.2 tls
47 1.1.1.1.2.2 tls #define LIST_HEAD(name) \
48 1.1.1.1.2.2 tls struct list_head name = LIST_HEAD_INIT(name)
49 1.1.1.1.2.2 tls
50 1.1.1.1.2.2 tls static inline void INIT_LIST_HEAD(struct list_head *list)
51 1.1.1.1.2.2 tls {
52 1.1.1.1.2.2 tls list->next = list;
53 1.1.1.1.2.2 tls list->prev = list;
54 1.1.1.1.2.2 tls }
55 1.1.1.1.2.2 tls
56 1.1.1.1.2.2 tls /*
57 1.1.1.1.2.2 tls * Insert a new entry between two known consecutive entries.
58 1.1.1.1.2.2 tls *
59 1.1.1.1.2.2 tls * This is only for internal list manipulation where we know
60 1.1.1.1.2.2 tls * the prev/next entries already!
61 1.1.1.1.2.2 tls */
62 1.1.1.1.2.2 tls #ifndef CONFIG_DEBUG_LIST
63 1.1.1.1.2.2 tls static inline void __list_add(struct list_head *new,
64 1.1.1.1.2.2 tls struct list_head *prev, struct list_head *next)
65 1.1.1.1.2.2 tls {
66 1.1.1.1.2.2 tls next->prev = new;
67 1.1.1.1.2.2 tls new->next = next;
68 1.1.1.1.2.2 tls new->prev = prev;
69 1.1.1.1.2.2 tls prev->next = new;
70 1.1.1.1.2.2 tls }
71 1.1.1.1.2.2 tls #else
72 1.1.1.1.2.2 tls extern void __list_add(struct list_head *new,
73 1.1.1.1.2.2 tls struct list_head *prev, struct list_head *next);
74 1.1.1.1.2.2 tls #endif
75 1.1.1.1.2.2 tls
76 1.1.1.1.2.2 tls /**
77 1.1.1.1.2.2 tls * list_add - add a new entry
78 1.1.1.1.2.2 tls * @new: new entry to be added
79 1.1.1.1.2.2 tls * @head: list head to add it after
80 1.1.1.1.2.2 tls *
81 1.1.1.1.2.2 tls * Insert a new entry after the specified head.
82 1.1.1.1.2.2 tls * This is good for implementing stacks.
83 1.1.1.1.2.2 tls */
84 1.1.1.1.2.2 tls static inline void list_add(struct list_head *new, struct list_head *head)
85 1.1.1.1.2.2 tls {
86 1.1.1.1.2.2 tls __list_add(new, head, head->next);
87 1.1.1.1.2.2 tls }
88 1.1.1.1.2.2 tls
89 1.1.1.1.2.2 tls /**
90 1.1.1.1.2.2 tls * list_add_tail - add a new entry
91 1.1.1.1.2.2 tls * @new: new entry to be added
92 1.1.1.1.2.2 tls * @head: list head to add it before
93 1.1.1.1.2.2 tls *
94 1.1.1.1.2.2 tls * Insert a new entry before the specified head.
95 1.1.1.1.2.2 tls * This is useful for implementing queues.
96 1.1.1.1.2.2 tls */
97 1.1.1.1.2.2 tls static inline void list_add_tail(struct list_head *new, struct list_head *head)
98 1.1.1.1.2.2 tls {
99 1.1.1.1.2.2 tls __list_add(new, head->prev, head);
100 1.1.1.1.2.2 tls }
101 1.1.1.1.2.2 tls
102 1.1.1.1.2.2 tls /*
103 1.1.1.1.2.2 tls * Delete a list entry by making the prev/next entries
104 1.1.1.1.2.2 tls * point to each other.
105 1.1.1.1.2.2 tls *
106 1.1.1.1.2.2 tls * This is only for internal list manipulation where we know
107 1.1.1.1.2.2 tls * the prev/next entries already!
108 1.1.1.1.2.2 tls */
109 1.1.1.1.2.2 tls static inline void __list_del(struct list_head *prev, struct list_head *next)
110 1.1.1.1.2.2 tls {
111 1.1.1.1.2.2 tls next->prev = prev;
112 1.1.1.1.2.2 tls prev->next = next;
113 1.1.1.1.2.2 tls }
114 1.1.1.1.2.2 tls
115 1.1.1.1.2.2 tls /**
116 1.1.1.1.2.2 tls * list_del - deletes entry from list.
117 1.1.1.1.2.2 tls * @entry: the element to delete from the list.
118 1.1.1.1.2.2 tls * Note: list_empty() on entry does not return true after this, the entry is
119 1.1.1.1.2.2 tls * in an undefined state.
120 1.1.1.1.2.2 tls */
121 1.1.1.1.2.2 tls #ifndef CONFIG_DEBUG_LIST
122 1.1.1.1.2.2 tls static inline void list_del(struct list_head *entry)
123 1.1.1.1.2.2 tls {
124 1.1.1.1.2.2 tls __list_del(entry->prev, entry->next);
125 1.1.1.1.2.2 tls entry->next = (void *)0xDEADBEEF;
126 1.1.1.1.2.2 tls entry->prev = (void *)0xBEEFDEAD;
127 1.1.1.1.2.2 tls }
128 1.1.1.1.2.2 tls #else
129 1.1.1.1.2.2 tls extern void list_del(struct list_head *entry);
130 1.1.1.1.2.2 tls #endif
131 1.1.1.1.2.2 tls
132 1.1.1.1.2.2 tls /**
133 1.1.1.1.2.2 tls * list_replace - replace old entry by new one
134 1.1.1.1.2.2 tls * @old : the element to be replaced
135 1.1.1.1.2.2 tls * @new : the new element to insert
136 1.1.1.1.2.2 tls *
137 1.1.1.1.2.2 tls * If @old was empty, it will be overwritten.
138 1.1.1.1.2.2 tls */
139 1.1.1.1.2.2 tls static inline void list_replace(struct list_head *old, struct list_head *new)
140 1.1.1.1.2.2 tls {
141 1.1.1.1.2.2 tls new->next = old->next;
142 1.1.1.1.2.2 tls new->next->prev = new;
143 1.1.1.1.2.2 tls new->prev = old->prev;
144 1.1.1.1.2.2 tls new->prev->next = new;
145 1.1.1.1.2.2 tls }
146 1.1.1.1.2.2 tls
147 1.1.1.1.2.2 tls static inline void list_replace_init(struct list_head *old,
148 1.1.1.1.2.2 tls struct list_head *new)
149 1.1.1.1.2.2 tls {
150 1.1.1.1.2.2 tls list_replace(old, new);
151 1.1.1.1.2.2 tls INIT_LIST_HEAD(old);
152 1.1.1.1.2.2 tls }
153 1.1.1.1.2.2 tls
154 1.1.1.1.2.2 tls /**
155 1.1.1.1.2.2 tls * list_del_init - deletes entry from list and reinitialize it.
156 1.1.1.1.2.2 tls * @entry: the element to delete from the list.
157 1.1.1.1.2.2 tls */
158 1.1.1.1.2.2 tls static inline void list_del_init(struct list_head *entry)
159 1.1.1.1.2.2 tls {
160 1.1.1.1.2.2 tls __list_del(entry->prev, entry->next);
161 1.1.1.1.2.2 tls INIT_LIST_HEAD(entry);
162 1.1.1.1.2.2 tls }
163 1.1.1.1.2.2 tls
164 1.1.1.1.2.2 tls /**
165 1.1.1.1.2.2 tls * list_move - delete from one list and add as another's head
166 1.1.1.1.2.2 tls * @list: the entry to move
167 1.1.1.1.2.2 tls * @head: the head that will precede our entry
168 1.1.1.1.2.2 tls */
169 1.1.1.1.2.2 tls static inline void list_move(struct list_head *list, struct list_head *head)
170 1.1.1.1.2.2 tls {
171 1.1.1.1.2.2 tls __list_del(list->prev, list->next);
172 1.1.1.1.2.2 tls list_add(list, head);
173 1.1.1.1.2.2 tls }
174 1.1.1.1.2.2 tls
175 1.1.1.1.2.2 tls /**
176 1.1.1.1.2.2 tls * list_move_tail - delete from one list and add as another's tail
177 1.1.1.1.2.2 tls * @list: the entry to move
178 1.1.1.1.2.2 tls * @head: the head that will follow our entry
179 1.1.1.1.2.2 tls */
180 1.1.1.1.2.2 tls static inline void list_move_tail(struct list_head *list,
181 1.1.1.1.2.2 tls struct list_head *head)
182 1.1.1.1.2.2 tls {
183 1.1.1.1.2.2 tls __list_del(list->prev, list->next);
184 1.1.1.1.2.2 tls list_add_tail(list, head);
185 1.1.1.1.2.2 tls }
186 1.1.1.1.2.2 tls
187 1.1.1.1.2.2 tls /**
188 1.1.1.1.2.2 tls * list_is_last - tests whether @list is the last entry in list @head
189 1.1.1.1.2.2 tls * @list: the entry to test
190 1.1.1.1.2.2 tls * @head: the head of the list
191 1.1.1.1.2.2 tls */
192 1.1.1.1.2.2 tls static inline int list_is_last(const struct list_head *list,
193 1.1.1.1.2.2 tls const struct list_head *head)
194 1.1.1.1.2.2 tls {
195 1.1.1.1.2.2 tls return list->next == head;
196 1.1.1.1.2.2 tls }
197 1.1.1.1.2.2 tls
198 1.1.1.1.2.2 tls /**
199 1.1.1.1.2.2 tls * list_empty - tests whether a list is empty
200 1.1.1.1.2.2 tls * @head: the list to test.
201 1.1.1.1.2.2 tls */
202 1.1.1.1.2.2 tls static inline int list_empty(const struct list_head *head)
203 1.1.1.1.2.2 tls {
204 1.1.1.1.2.2 tls return head->next == head;
205 1.1.1.1.2.2 tls }
206 1.1.1.1.2.2 tls
207 1.1.1.1.2.2 tls /**
208 1.1.1.1.2.2 tls * list_empty_careful - tests whether a list is empty and not being modified
209 1.1.1.1.2.2 tls * @head: the list to test
210 1.1.1.1.2.2 tls *
211 1.1.1.1.2.2 tls * Description:
212 1.1.1.1.2.2 tls * tests whether a list is empty _and_ checks that no other CPU might be
213 1.1.1.1.2.2 tls * in the process of modifying either member (next or prev)
214 1.1.1.1.2.2 tls *
215 1.1.1.1.2.2 tls * NOTE: using list_empty_careful() without synchronization
216 1.1.1.1.2.2 tls * can only be safe if the only activity that can happen
217 1.1.1.1.2.2 tls * to the list entry is list_del_init(). Eg. it cannot be used
218 1.1.1.1.2.2 tls * if another CPU could re-list_add() it.
219 1.1.1.1.2.2 tls */
220 1.1.1.1.2.2 tls static inline int list_empty_careful(const struct list_head *head)
221 1.1.1.1.2.2 tls {
222 1.1.1.1.2.2 tls struct list_head *next = head->next;
223 1.1.1.1.2.2 tls return (next == head) && (next == head->prev);
224 1.1.1.1.2.2 tls }
225 1.1.1.1.2.2 tls
226 1.1.1.1.2.2 tls /**
227 1.1.1.1.2.2 tls * list_is_singular - tests whether a list has just one entry.
228 1.1.1.1.2.2 tls * @head: the list to test.
229 1.1.1.1.2.2 tls */
230 1.1.1.1.2.2 tls static inline int list_is_singular(const struct list_head *head)
231 1.1.1.1.2.2 tls {
232 1.1.1.1.2.2 tls return !list_empty(head) && (head->next == head->prev);
233 1.1.1.1.2.2 tls }
234 1.1.1.1.2.2 tls
235 1.1.1.1.2.2 tls static inline void __list_cut_position(struct list_head *list,
236 1.1.1.1.2.2 tls struct list_head *head,
237 1.1.1.1.2.2 tls struct list_head *entry)
238 1.1.1.1.2.2 tls {
239 1.1.1.1.2.2 tls struct list_head *new_first = entry->next;
240 1.1.1.1.2.2 tls list->next = head->next;
241 1.1.1.1.2.2 tls list->next->prev = list;
242 1.1.1.1.2.2 tls list->prev = entry;
243 1.1.1.1.2.2 tls entry->next = list;
244 1.1.1.1.2.2 tls head->next = new_first;
245 1.1.1.1.2.2 tls new_first->prev = head;
246 1.1.1.1.2.2 tls }
247 1.1.1.1.2.2 tls
248 1.1.1.1.2.2 tls /**
249 1.1.1.1.2.2 tls * list_cut_position - cut a list into two
250 1.1.1.1.2.2 tls * @list: a new list to add all removed entries
251 1.1.1.1.2.2 tls * @head: a list with entries
252 1.1.1.1.2.2 tls * @entry: an entry within head, could be the head itself
253 1.1.1.1.2.2 tls * and if so we won't cut the list
254 1.1.1.1.2.2 tls *
255 1.1.1.1.2.2 tls * This helper moves the initial part of @head, up to and
256 1.1.1.1.2.2 tls * including @entry, from @head to @list. You should
257 1.1.1.1.2.2 tls * pass on @entry an element you know is on @head. @list
258 1.1.1.1.2.2 tls * should be an empty list or a list you do not care about
259 1.1.1.1.2.2 tls * losing its data.
260 1.1.1.1.2.2 tls *
261 1.1.1.1.2.2 tls */
262 1.1.1.1.2.2 tls static inline void list_cut_position(struct list_head *list,
263 1.1.1.1.2.2 tls struct list_head *head,
264 1.1.1.1.2.2 tls struct list_head *entry)
265 1.1.1.1.2.2 tls {
266 1.1.1.1.2.2 tls if (list_empty(head))
267 1.1.1.1.2.2 tls return;
268 1.1.1.1.2.2 tls if (list_is_singular(head) && (head->next != entry && head != entry))
269 1.1.1.1.2.2 tls return;
270 1.1.1.1.2.2 tls if (entry == head)
271 1.1.1.1.2.2 tls INIT_LIST_HEAD(list);
272 1.1.1.1.2.2 tls else
273 1.1.1.1.2.2 tls __list_cut_position(list, head, entry);
274 1.1.1.1.2.2 tls }
275 1.1.1.1.2.2 tls
276 1.1.1.1.2.2 tls static inline void __list_splice(const struct list_head *list,
277 1.1.1.1.2.2 tls struct list_head *prev, struct list_head *next)
278 1.1.1.1.2.2 tls {
279 1.1.1.1.2.2 tls struct list_head *first = list->next;
280 1.1.1.1.2.2 tls struct list_head *last = list->prev;
281 1.1.1.1.2.2 tls
282 1.1.1.1.2.2 tls first->prev = prev;
283 1.1.1.1.2.2 tls prev->next = first;
284 1.1.1.1.2.2 tls
285 1.1.1.1.2.2 tls last->next = next;
286 1.1.1.1.2.2 tls next->prev = last;
287 1.1.1.1.2.2 tls }
288 1.1.1.1.2.2 tls
289 1.1.1.1.2.2 tls /**
290 1.1.1.1.2.2 tls * list_splice - join two lists, this is designed for stacks
291 1.1.1.1.2.2 tls * @list: the new list to add.
292 1.1.1.1.2.2 tls * @head: the place to add it in the first list.
293 1.1.1.1.2.2 tls */
294 1.1.1.1.2.2 tls static inline void list_splice(const struct list_head *list,
295 1.1.1.1.2.2 tls struct list_head *head)
296 1.1.1.1.2.2 tls {
297 1.1.1.1.2.2 tls if (!list_empty(list))
298 1.1.1.1.2.2 tls __list_splice(list, head, head->next);
299 1.1.1.1.2.2 tls }
300 1.1.1.1.2.2 tls
301 1.1.1.1.2.2 tls /**
302 1.1.1.1.2.2 tls * list_splice_tail - join two lists, each list being a queue
303 1.1.1.1.2.2 tls * @list: the new list to add.
304 1.1.1.1.2.2 tls * @head: the place to add it in the first list.
305 1.1.1.1.2.2 tls */
306 1.1.1.1.2.2 tls static inline void list_splice_tail(struct list_head *list,
307 1.1.1.1.2.2 tls struct list_head *head)
308 1.1.1.1.2.2 tls {
309 1.1.1.1.2.2 tls if (!list_empty(list))
310 1.1.1.1.2.2 tls __list_splice(list, head->prev, head);
311 1.1.1.1.2.2 tls }
312 1.1.1.1.2.2 tls
313 1.1.1.1.2.2 tls /**
314 1.1.1.1.2.2 tls * list_splice_init - join two lists and reinitialise the emptied list.
315 1.1.1.1.2.2 tls * @list: the new list to add.
316 1.1.1.1.2.2 tls * @head: the place to add it in the first list.
317 1.1.1.1.2.2 tls *
318 1.1.1.1.2.2 tls * The list at @list is reinitialised
319 1.1.1.1.2.2 tls */
320 1.1.1.1.2.2 tls static inline void list_splice_init(struct list_head *list,
321 1.1.1.1.2.2 tls struct list_head *head)
322 1.1.1.1.2.2 tls {
323 1.1.1.1.2.2 tls if (!list_empty(list)) {
324 1.1.1.1.2.2 tls __list_splice(list, head, head->next);
325 1.1.1.1.2.2 tls INIT_LIST_HEAD(list);
326 1.1.1.1.2.2 tls }
327 1.1.1.1.2.2 tls }
328 1.1.1.1.2.2 tls
329 1.1.1.1.2.2 tls /**
330 1.1.1.1.2.2 tls * list_splice_tail_init - join two lists and reinitialise the emptied list
331 1.1.1.1.2.2 tls * @list: the new list to add.
332 1.1.1.1.2.2 tls * @head: the place to add it in the first list.
333 1.1.1.1.2.2 tls *
334 1.1.1.1.2.2 tls * Each of the lists is a queue.
335 1.1.1.1.2.2 tls * The list at @list is reinitialised
336 1.1.1.1.2.2 tls */
337 1.1.1.1.2.2 tls static inline void list_splice_tail_init(struct list_head *list,
338 1.1.1.1.2.2 tls struct list_head *head)
339 1.1.1.1.2.2 tls {
340 1.1.1.1.2.2 tls if (!list_empty(list)) {
341 1.1.1.1.2.2 tls __list_splice(list, head->prev, head);
342 1.1.1.1.2.2 tls INIT_LIST_HEAD(list);
343 1.1.1.1.2.2 tls }
344 1.1.1.1.2.2 tls }
345 1.1.1.1.2.2 tls
346 1.1.1.1.2.2 tls /**
347 1.1.1.1.2.2 tls * list_entry - get the struct for this entry
348 1.1.1.1.2.2 tls * @ptr: the &struct list_head pointer.
349 1.1.1.1.2.2 tls * @type: the type of the struct this is embedded in.
350 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
351 1.1.1.1.2.2 tls */
352 1.1.1.1.2.2 tls #define list_entry(ptr, type, member) \
353 1.1.1.1.2.2 tls container_of(ptr, type, member)
354 1.1.1.1.2.2 tls
355 1.1.1.1.2.2 tls /**
356 1.1.1.1.2.2 tls * list_first_entry - get the first element from a list
357 1.1.1.1.2.2 tls * @ptr: the list head to take the element from.
358 1.1.1.1.2.2 tls * @type: the type of the struct this is embedded in.
359 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
360 1.1.1.1.2.2 tls *
361 1.1.1.1.2.2 tls * Note, that list is expected to be not empty.
362 1.1.1.1.2.2 tls */
363 1.1.1.1.2.2 tls #define list_first_entry(ptr, type, member) \
364 1.1.1.1.2.2 tls list_entry((ptr)->next, type, member)
365 1.1.1.1.2.2 tls
366 1.1.1.1.2.2 tls /**
367 1.1.1.1.2.2 tls * list_for_each - iterate over a list
368 1.1.1.1.2.2 tls * @pos: the &struct list_head to use as a loop cursor.
369 1.1.1.1.2.2 tls * @head: the head for your list.
370 1.1.1.1.2.2 tls */
371 1.1.1.1.2.2 tls #define list_for_each(pos, head) \
372 1.1.1.1.2.2 tls for (pos = (head)->next; prefetch(pos->next), pos != (head); \
373 1.1.1.1.2.2 tls pos = pos->next)
374 1.1.1.1.2.2 tls
375 1.1.1.1.2.2 tls /**
376 1.1.1.1.2.2 tls * list_for_each_prev - iterate over a list backwards
377 1.1.1.1.2.2 tls * @pos: the &struct list_head to use as a loop cursor.
378 1.1.1.1.2.2 tls * @head: the head for your list.
379 1.1.1.1.2.2 tls */
380 1.1.1.1.2.2 tls #define list_for_each_prev(pos, head) \
381 1.1.1.1.2.2 tls for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
382 1.1.1.1.2.2 tls pos = pos->prev)
383 1.1.1.1.2.2 tls
384 1.1.1.1.2.2 tls /**
385 1.1.1.1.2.2 tls * list_for_each_safe - iterate over a list safe against removal of list entry
386 1.1.1.1.2.2 tls * @pos: the &struct list_head to use as a loop cursor.
387 1.1.1.1.2.2 tls * @n: another &struct list_head to use as temporary storage
388 1.1.1.1.2.2 tls * @head: the head for your list.
389 1.1.1.1.2.2 tls */
390 1.1.1.1.2.2 tls #define list_for_each_safe(pos, n, head) \
391 1.1.1.1.2.2 tls for (pos = (head)->next, n = pos->next; pos != (head); \
392 1.1.1.1.2.2 tls pos = n, n = pos->next)
393 1.1.1.1.2.2 tls
394 1.1.1.1.2.2 tls /**
395 1.1.1.1.2.2 tls * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
396 1.1.1.1.2.2 tls * @pos: the &struct list_head to use as a loop cursor.
397 1.1.1.1.2.2 tls * @n: another &struct list_head to use as temporary storage
398 1.1.1.1.2.2 tls * @head: the head for your list.
399 1.1.1.1.2.2 tls */
400 1.1.1.1.2.2 tls #define list_for_each_prev_safe(pos, n, head) \
401 1.1.1.1.2.2 tls for (pos = (head)->prev, n = pos->prev; \
402 1.1.1.1.2.2 tls prefetch(pos->prev), pos != (head); \
403 1.1.1.1.2.2 tls pos = n, n = pos->prev)
404 1.1.1.1.2.2 tls
405 1.1.1.1.2.2 tls /**
406 1.1.1.1.2.2 tls * list_for_each_entry - iterate over list of given type
407 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
408 1.1.1.1.2.2 tls * @head: the head for your list.
409 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
410 1.1.1.1.2.2 tls */
411 1.1.1.1.2.2 tls #define list_for_each_entry(pos, head, member) \
412 1.1.1.1.2.2 tls for (pos = list_entry((head)->next, typeof(*pos), member); \
413 1.1.1.1.2.2 tls &pos->member != (head); \
414 1.1.1.1.2.2 tls pos = list_entry(pos->member.next, typeof(*pos), member))
415 1.1.1.1.2.2 tls
416 1.1.1.1.2.2 tls /**
417 1.1.1.1.2.2 tls * list_for_each_entry_reverse - iterate backwards over list of given type.
418 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
419 1.1.1.1.2.2 tls * @head: the head for your list.
420 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
421 1.1.1.1.2.2 tls */
422 1.1.1.1.2.2 tls #define list_for_each_entry_reverse(pos, head, member) \
423 1.1.1.1.2.2 tls for (pos = list_entry((head)->prev, typeof(*pos), member); \
424 1.1.1.1.2.2 tls prefetch(pos->member.prev), &pos->member != (head); \
425 1.1.1.1.2.2 tls pos = list_entry(pos->member.prev, typeof(*pos), member))
426 1.1.1.1.2.2 tls
427 1.1.1.1.2.2 tls /**
428 1.1.1.1.2.2 tls * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
429 1.1.1.1.2.2 tls * @pos: the type * to use as a start point
430 1.1.1.1.2.2 tls * @head: the head of the list
431 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
432 1.1.1.1.2.2 tls *
433 1.1.1.1.2.2 tls * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
434 1.1.1.1.2.2 tls */
435 1.1.1.1.2.2 tls #define list_prepare_entry(pos, head, member) \
436 1.1.1.1.2.2 tls ((pos) ? : list_entry(head, typeof(*pos), member))
437 1.1.1.1.2.2 tls
438 1.1.1.1.2.2 tls /**
439 1.1.1.1.2.2 tls * list_for_each_entry_continue - continue iteration over list of given type
440 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
441 1.1.1.1.2.2 tls * @head: the head for your list.
442 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
443 1.1.1.1.2.2 tls *
444 1.1.1.1.2.2 tls * Continue to iterate over list of given type, continuing after
445 1.1.1.1.2.2 tls * the current position.
446 1.1.1.1.2.2 tls */
447 1.1.1.1.2.2 tls #define list_for_each_entry_continue(pos, head, member) \
448 1.1.1.1.2.2 tls for (pos = list_entry(pos->member.next, typeof(*pos), member); \
449 1.1.1.1.2.2 tls prefetch(pos->member.next), &pos->member != (head); \
450 1.1.1.1.2.2 tls pos = list_entry(pos->member.next, typeof(*pos), member))
451 1.1.1.1.2.2 tls
452 1.1.1.1.2.2 tls /**
453 1.1.1.1.2.2 tls * list_for_each_entry_continue_reverse - iterate backwards from the given point
454 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
455 1.1.1.1.2.2 tls * @head: the head for your list.
456 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
457 1.1.1.1.2.2 tls *
458 1.1.1.1.2.2 tls * Start to iterate over list of given type backwards, continuing after
459 1.1.1.1.2.2 tls * the current position.
460 1.1.1.1.2.2 tls */
461 1.1.1.1.2.2 tls #define list_for_each_entry_continue_reverse(pos, head, member) \
462 1.1.1.1.2.2 tls for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
463 1.1.1.1.2.2 tls prefetch(pos->member.prev), &pos->member != (head); \
464 1.1.1.1.2.2 tls pos = list_entry(pos->member.prev, typeof(*pos), member))
465 1.1.1.1.2.2 tls
466 1.1.1.1.2.2 tls /**
467 1.1.1.1.2.2 tls * list_for_each_entry_from - iterate over list of given type from the current point
468 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
469 1.1.1.1.2.2 tls * @head: the head for your list.
470 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
471 1.1.1.1.2.2 tls *
472 1.1.1.1.2.2 tls * Iterate over list of given type, continuing from current position.
473 1.1.1.1.2.2 tls */
474 1.1.1.1.2.2 tls #define list_for_each_entry_from(pos, head, member) \
475 1.1.1.1.2.2 tls for (; prefetch(pos->member.next), &pos->member != (head); \
476 1.1.1.1.2.2 tls pos = list_entry(pos->member.next, typeof(*pos), member))
477 1.1.1.1.2.2 tls
478 1.1.1.1.2.2 tls /**
479 1.1.1.1.2.2 tls * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
480 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
481 1.1.1.1.2.2 tls * @n: another type * to use as temporary storage
482 1.1.1.1.2.2 tls * @head: the head for your list.
483 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
484 1.1.1.1.2.2 tls */
485 1.1.1.1.2.2 tls #define list_for_each_entry_safe(pos, n, head, member) \
486 1.1.1.1.2.2 tls for (pos = list_entry((head)->next, typeof(*pos), member), \
487 1.1.1.1.2.2 tls n = list_entry(pos->member.next, typeof(*pos), member); \
488 1.1.1.1.2.2 tls &pos->member != (head); \
489 1.1.1.1.2.2 tls pos = n, n = list_entry(n->member.next, typeof(*n), member))
490 1.1.1.1.2.2 tls
491 1.1.1.1.2.2 tls /**
492 1.1.1.1.2.2 tls * list_for_each_entry_safe_continue
493 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
494 1.1.1.1.2.2 tls * @n: another type * to use as temporary storage
495 1.1.1.1.2.2 tls * @head: the head for your list.
496 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
497 1.1.1.1.2.2 tls *
498 1.1.1.1.2.2 tls * Iterate over list of given type, continuing after current point,
499 1.1.1.1.2.2 tls * safe against removal of list entry.
500 1.1.1.1.2.2 tls */
501 1.1.1.1.2.2 tls #define list_for_each_entry_safe_continue(pos, n, head, member) \
502 1.1.1.1.2.2 tls for (pos = list_entry(pos->member.next, typeof(*pos), member), \
503 1.1.1.1.2.2 tls n = list_entry(pos->member.next, typeof(*pos), member); \
504 1.1.1.1.2.2 tls &pos->member != (head); \
505 1.1.1.1.2.2 tls pos = n, n = list_entry(n->member.next, typeof(*n), member))
506 1.1.1.1.2.2 tls
507 1.1.1.1.2.2 tls /**
508 1.1.1.1.2.2 tls * list_for_each_entry_safe_from
509 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
510 1.1.1.1.2.2 tls * @n: another type * to use as temporary storage
511 1.1.1.1.2.2 tls * @head: the head for your list.
512 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
513 1.1.1.1.2.2 tls *
514 1.1.1.1.2.2 tls * Iterate over list of given type from current point, safe against
515 1.1.1.1.2.2 tls * removal of list entry.
516 1.1.1.1.2.2 tls */
517 1.1.1.1.2.2 tls #define list_for_each_entry_safe_from(pos, n, head, member) \
518 1.1.1.1.2.2 tls for (n = list_entry(pos->member.next, typeof(*pos), member); \
519 1.1.1.1.2.2 tls &pos->member != (head); \
520 1.1.1.1.2.2 tls pos = n, n = list_entry(n->member.next, typeof(*n), member))
521 1.1.1.1.2.2 tls
522 1.1.1.1.2.2 tls /**
523 1.1.1.1.2.2 tls * list_for_each_entry_safe_reverse
524 1.1.1.1.2.2 tls * @pos: the type * to use as a loop cursor.
525 1.1.1.1.2.2 tls * @n: another type * to use as temporary storage
526 1.1.1.1.2.2 tls * @head: the head for your list.
527 1.1.1.1.2.2 tls * @member: the name of the list_struct within the struct.
528 1.1.1.1.2.2 tls *
529 1.1.1.1.2.2 tls * Iterate backwards over list of given type, safe against removal
530 1.1.1.1.2.2 tls * of list entry.
531 1.1.1.1.2.2 tls */
532 1.1.1.1.2.2 tls #define list_for_each_entry_safe_reverse(pos, n, head, member) \
533 1.1.1.1.2.2 tls for (pos = list_entry((head)->prev, typeof(*pos), member), \
534 1.1.1.1.2.2 tls n = list_entry(pos->member.prev, typeof(*pos), member); \
535 1.1.1.1.2.2 tls &pos->member != (head); \
536 1.1.1.1.2.2 tls pos = n, n = list_entry(n->member.prev, typeof(*n), member))
537 1.1.1.1.2.2 tls
538 1.1.1.1.2.2 tls struct offset {
539 1.1.1.1.2.2 tls struct list_head list;
540 1.1.1.1.2.2 tls unsigned offset;
541 1.1.1.1.2.2 tls };
542 1.1.1.1.2.2 tls
543 1.1.1.1.2.2 tls struct table {
544 1.1.1.1.2.2 tls struct list_head offsets;
545 1.1.1.1.2.2 tls unsigned offset_max;
546 1.1.1.1.2.2 tls unsigned nentry;
547 1.1.1.1.2.2 tls unsigned *table;
548 1.1.1.1.2.2 tls char *gpu_prefix;
549 1.1.1.1.2.2 tls };
550 1.1.1.1.2.2 tls
551 1.1.1.1.2.2 tls static struct offset *offset_new(unsigned o)
552 1.1.1.1.2.2 tls {
553 1.1.1.1.2.2 tls struct offset *offset;
554 1.1.1.1.2.2 tls
555 1.1.1.1.2.2 tls offset = (struct offset *)malloc(sizeof(struct offset));
556 1.1.1.1.2.2 tls if (offset) {
557 1.1.1.1.2.2 tls INIT_LIST_HEAD(&offset->list);
558 1.1.1.1.2.2 tls offset->offset = o;
559 1.1.1.1.2.2 tls }
560 1.1.1.1.2.2 tls return offset;
561 1.1.1.1.2.2 tls }
562 1.1.1.1.2.2 tls
563 1.1.1.1.2.2 tls static void table_offset_add(struct table *t, struct offset *offset)
564 1.1.1.1.2.2 tls {
565 1.1.1.1.2.2 tls list_add_tail(&offset->list, &t->offsets);
566 1.1.1.1.2.2 tls }
567 1.1.1.1.2.2 tls
568 1.1.1.1.2.2 tls static void table_init(struct table *t)
569 1.1.1.1.2.2 tls {
570 1.1.1.1.2.2 tls INIT_LIST_HEAD(&t->offsets);
571 1.1.1.1.2.2 tls t->offset_max = 0;
572 1.1.1.1.2.2 tls t->nentry = 0;
573 1.1.1.1.2.2 tls t->table = NULL;
574 1.1.1.1.2.2 tls }
575 1.1.1.1.2.2 tls
576 1.1.1.1.2.2 tls static void table_print(struct table *t)
577 1.1.1.1.2.2 tls {
578 1.1.1.1.2.2 tls unsigned nlloop, i, j, n, c, id;
579 1.1.1.1.2.2 tls
580 1.1.1.1.2.2 tls nlloop = (t->nentry + 3) / 4;
581 1.1.1.1.2.2 tls c = t->nentry;
582 1.1.1.1.2.2 tls printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
583 1.1.1.1.2.2 tls t->nentry);
584 1.1.1.1.2.2 tls for (i = 0, id = 0; i < nlloop; i++) {
585 1.1.1.1.2.2 tls n = 4;
586 1.1.1.1.2.2 tls if (n > c)
587 1.1.1.1.2.2 tls n = c;
588 1.1.1.1.2.2 tls c -= n;
589 1.1.1.1.2.2 tls for (j = 0; j < n; j++) {
590 1.1.1.1.2.2 tls if (j == 0)
591 1.1.1.1.2.2 tls printf("\t");
592 1.1.1.1.2.2 tls else
593 1.1.1.1.2.2 tls printf(" ");
594 1.1.1.1.2.2 tls printf("0x%08X,", t->table[id++]);
595 1.1.1.1.2.2 tls }
596 1.1.1.1.2.2 tls printf("\n");
597 1.1.1.1.2.2 tls }
598 1.1.1.1.2.2 tls printf("};\n");
599 1.1.1.1.2.2 tls }
600 1.1.1.1.2.2 tls
601 1.1.1.1.2.2 tls static int table_build(struct table *t)
602 1.1.1.1.2.2 tls {
603 1.1.1.1.2.2 tls struct offset *offset;
604 1.1.1.1.2.2 tls unsigned i, m;
605 1.1.1.1.2.2 tls
606 1.1.1.1.2.2 tls t->nentry = ((t->offset_max >> 2) + 31) / 32;
607 1.1.1.1.2.2 tls t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
608 1.1.1.1.2.2 tls if (t->table == NULL)
609 1.1.1.1.2.2 tls return -1;
610 1.1.1.1.2.2 tls memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
611 1.1.1.1.2.2 tls list_for_each_entry(offset, &t->offsets, list) {
612 1.1.1.1.2.2 tls i = (offset->offset >> 2) / 32;
613 1.1.1.1.2.2 tls m = (offset->offset >> 2) & 31;
614 1.1.1.1.2.2 tls m = 1 << m;
615 1.1.1.1.2.2 tls t->table[i] ^= m;
616 1.1.1.1.2.2 tls }
617 1.1.1.1.2.2 tls return 0;
618 1.1.1.1.2.2 tls }
619 1.1.1.1.2.2 tls
620 1.1.1.1.2.2 tls static char gpu_name[10];
621 1.1.1.1.2.2 tls static int parser_auth(struct table *t, const char *filename)
622 1.1.1.1.2.2 tls {
623 1.1.1.1.2.2 tls FILE *file;
624 1.1.1.1.2.2 tls regex_t mask_rex;
625 1.1.1.1.2.2 tls regmatch_t match[4];
626 1.1.1.1.2.2 tls char buf[1024];
627 1.1.1.1.2.2 tls size_t end;
628 1.1.1.1.2.2 tls int len;
629 1.1.1.1.2.2 tls int done = 0;
630 1.1.1.1.2.2 tls int r;
631 1.1.1.1.2.2 tls unsigned o;
632 1.1.1.1.2.2 tls struct offset *offset;
633 1.1.1.1.2.2 tls char last_reg_s[10];
634 1.1.1.1.2.2 tls int last_reg;
635 1.1.1.1.2.2 tls
636 1.1.1.1.2.2 tls if (regcomp
637 1.1.1.1.2.2 tls (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
638 1.1.1.1.2.2 tls fprintf(stderr, "Failed to compile regular expression\n");
639 1.1.1.1.2.2 tls return -1;
640 1.1.1.1.2.2 tls }
641 1.1.1.1.2.2 tls file = fopen(filename, "r");
642 1.1.1.1.2.2 tls if (file == NULL) {
643 1.1.1.1.2.2 tls fprintf(stderr, "Failed to open: %s\n", filename);
644 1.1.1.1.2.2 tls return -1;
645 1.1.1.1.2.2 tls }
646 1.1.1.1.2.2 tls fseek(file, 0, SEEK_END);
647 1.1.1.1.2.2 tls end = ftell(file);
648 1.1.1.1.2.2 tls fseek(file, 0, SEEK_SET);
649 1.1.1.1.2.2 tls
650 1.1.1.1.2.2 tls /* get header */
651 1.1.1.1.2.2 tls if (fgets(buf, 1024, file) == NULL) {
652 1.1.1.1.2.2 tls fclose(file);
653 1.1.1.1.2.2 tls return -1;
654 1.1.1.1.2.2 tls }
655 1.1.1.1.2.2 tls
656 1.1.1.1.2.2 tls /* first line will contain the last register
657 1.1.1.1.2.2 tls * and gpu name */
658 1.1.1.1.2.2 tls sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
659 1.1.1.1.2.2 tls t->gpu_prefix = gpu_name;
660 1.1.1.1.2.2 tls last_reg = strtol(last_reg_s, NULL, 16);
661 1.1.1.1.2.2 tls
662 1.1.1.1.2.2 tls do {
663 1.1.1.1.2.2 tls if (fgets(buf, 1024, file) == NULL) {
664 1.1.1.1.2.2 tls fclose(file);
665 1.1.1.1.2.2 tls return -1;
666 1.1.1.1.2.2 tls }
667 1.1.1.1.2.2 tls len = strlen(buf);
668 1.1.1.1.2.2 tls if (ftell(file) == end)
669 1.1.1.1.2.2 tls done = 1;
670 1.1.1.1.2.2 tls if (len) {
671 1.1.1.1.2.2 tls r = regexec(&mask_rex, buf, 4, match, 0);
672 1.1.1.1.2.2 tls if (r == REG_NOMATCH) {
673 1.1.1.1.2.2 tls } else if (r) {
674 1.1.1.1.2.2 tls fprintf(stderr,
675 1.1.1.1.2.2 tls "Error matching regular expression %d in %s\n",
676 1.1.1.1.2.2 tls r, filename);
677 1.1.1.1.2.2 tls fclose(file);
678 1.1.1.1.2.2 tls return -1;
679 1.1.1.1.2.2 tls } else {
680 1.1.1.1.2.2 tls buf[match[0].rm_eo] = 0;
681 1.1.1.1.2.2 tls buf[match[1].rm_eo] = 0;
682 1.1.1.1.2.2 tls buf[match[2].rm_eo] = 0;
683 1.1.1.1.2.2 tls o = strtol(&buf[match[1].rm_so], NULL, 16);
684 1.1.1.1.2.2 tls offset = offset_new(o);
685 1.1.1.1.2.2 tls table_offset_add(t, offset);
686 1.1.1.1.2.2 tls if (o > t->offset_max)
687 1.1.1.1.2.2 tls t->offset_max = o;
688 1.1.1.1.2.2 tls }
689 1.1.1.1.2.2 tls }
690 1.1.1.1.2.2 tls } while (!done);
691 1.1.1.1.2.2 tls fclose(file);
692 1.1.1.1.2.2 tls if (t->offset_max < last_reg)
693 1.1.1.1.2.2 tls t->offset_max = last_reg;
694 1.1.1.1.2.2 tls return table_build(t);
695 1.1.1.1.2.2 tls }
696 1.1.1.1.2.2 tls
697 1.1.1.1.2.2 tls int main(int argc, char *argv[])
698 1.1.1.1.2.2 tls {
699 1.1.1.1.2.2 tls struct table t;
700 1.1.1.1.2.2 tls
701 1.1.1.1.2.2 tls if (argc != 2) {
702 1.1.1.1.2.2 tls fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
703 1.1.1.1.2.2 tls exit(1);
704 1.1.1.1.2.2 tls }
705 1.1.1.1.2.2 tls table_init(&t);
706 1.1.1.1.2.2 tls if (parser_auth(&t, argv[1])) {
707 1.1.1.1.2.2 tls fprintf(stderr, "Failed to parse file %s\n", argv[1]);
708 1.1.1.1.2.2 tls return -1;
709 1.1.1.1.2.2 tls }
710 1.1.1.1.2.2 tls table_print(&t);
711 1.1.1.1.2.2 tls return 0;
712 1.1.1.1.2.2 tls }
713