150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/* utility to create the register check tables
250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * this includes inlined list.h safe for userspace.
350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Copyright 2009 Jerome Glisse
550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Copyright 2009 Red Hat Inc.
650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Authors:
850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * 	Jerome Glisse
950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * 	Dave Airlie
1050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
1150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
1250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <sys/types.h>
1350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <stdlib.h>
1450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <string.h>
1550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <stdio.h>
1650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <regex.h>
1750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#include <libgen.h>
1850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
1950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
2050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
2150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * container_of - cast a member of a structure out to the containing structure
2250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @ptr:    the pointer to the member.
2350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @type:   the type of the container struct this is embedded in.
2450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member: the name of the member within the struct.
2550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
2650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
2750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define container_of(ptr, type, member) ({          \
28689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	const typeof(((type *)0)->member)*__mptr = (ptr);    \
29689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		     (type *)((char *)__mptr - offsetof(type, member)); })
3050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
3150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/*
3250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Simple doubly linked list implementation.
3350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
3450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Some of the internal functions ("__xxx") are useful when
3550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * manipulating whole lists rather than single entries, as
3650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * sometimes we already know the next/prev entries and we can
3750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * generate better code by using them directly rather than
3850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * using the generic single-entry routines.
3950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
4050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
4150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestruct list_head {
4250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head *next, *prev;
4350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie};
4450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
4550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define LIST_HEAD_INIT(name) { &(name), &(name) }
4650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
4750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define LIST_HEAD(name) \
4850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head name = LIST_HEAD_INIT(name)
4950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void INIT_LIST_HEAD(struct list_head *list)
5150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
5250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list->next = list;
5350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list->prev = list;
5450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
5550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/*
5750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Insert a new entry between two known consecutive entries.
5850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
5950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * This is only for internal list manipulation where we know
6050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * the prev/next entries already!
6150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
6250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#ifndef CONFIG_DEBUG_LIST
6350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void __list_add(struct list_head *new,
64689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			      struct list_head *prev, struct list_head *next)
6550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
6650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	next->prev = new;
6750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->next = next;
6850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->prev = prev;
6950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	prev->next = new;
7050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
7150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#else
7250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlieextern void __list_add(struct list_head *new,
73689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		       struct list_head *prev, struct list_head *next);
7450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#endif
7550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
7650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
7750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_add - add a new entry
7850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @new: new entry to be added
7950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: list head to add it after
8050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
8150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Insert a new entry after the specified head.
8250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * This is good for implementing stacks.
8350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
8450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_add(struct list_head *new, struct list_head *head)
8550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
8650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_add(new, head, head->next);
8750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
8850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
8950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
9050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_add_tail - add a new entry
9150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @new: new entry to be added
9250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: list head to add it before
9350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
9450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Insert a new entry before the specified head.
9550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * This is useful for implementing queues.
9650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
9750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_add_tail(struct list_head *new, struct list_head *head)
9850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
9950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_add(new, head->prev, head);
10050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
10150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
10250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/*
10350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Delete a list entry by making the prev/next entries
10450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * point to each other.
10550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
10650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * This is only for internal list manipulation where we know
10750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * the prev/next entries already!
10850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
109689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airliestatic inline void __list_del(struct list_head *prev, struct list_head *next)
11050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
11150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	next->prev = prev;
11250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	prev->next = next;
11350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
11450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
11550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
11650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_del - deletes entry from list.
11750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @entry: the element to delete from the list.
11850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Note: list_empty() on entry does not return true after this, the entry is
11950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * in an undefined state.
12050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
12150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#ifndef CONFIG_DEBUG_LIST
12250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_del(struct list_head *entry)
12350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
12450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_del(entry->prev, entry->next);
125689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	entry->next = (void *)0xDEADBEEF;
126689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	entry->prev = (void *)0xBEEFDEAD;
12750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
12850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#else
12950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlieextern void list_del(struct list_head *entry);
13050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#endif
13150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
13250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
13350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_replace - replace old entry by new one
13450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @old : the element to be replaced
13550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @new : the new element to insert
13650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
13750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * If @old was empty, it will be overwritten.
13850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
139689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airliestatic inline void list_replace(struct list_head *old, struct list_head *new)
14050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
14150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->next = old->next;
14250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->next->prev = new;
14350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->prev = old->prev;
14450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new->prev->next = new;
14550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
14650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
14750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_replace_init(struct list_head *old,
148689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				     struct list_head *new)
14950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
15050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list_replace(old, new);
15150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	INIT_LIST_HEAD(old);
15250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
15350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
15450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
15550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_del_init - deletes entry from list and reinitialize it.
15650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @entry: the element to delete from the list.
15750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
15850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_del_init(struct list_head *entry)
15950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
16050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_del(entry->prev, entry->next);
16150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	INIT_LIST_HEAD(entry);
16250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
16350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
16450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
16550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_move - delete from one list and add as another's head
16650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the entry to move
16750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the head that will precede our entry
16850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
16950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_move(struct list_head *list, struct list_head *head)
17050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
17150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_del(list->prev, list->next);
17250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list_add(list, head);
17350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
17450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
17550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
17650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_move_tail - delete from one list and add as another's tail
17750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the entry to move
17850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the head that will follow our entry
17950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
18050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_move_tail(struct list_head *list,
18150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie				  struct list_head *head)
18250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
18350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	__list_del(list->prev, list->next);
18450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list_add_tail(list, head);
18550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
18650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
18750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
18850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_is_last - tests whether @list is the last entry in list @head
18950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the entry to test
19050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the head of the list
19150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
19250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline int list_is_last(const struct list_head *list,
193689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			       const struct list_head *head)
19450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
19550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	return list->next == head;
19650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
19750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
19850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
19950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_empty - tests whether a list is empty
20050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the list to test.
20150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
20250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline int list_empty(const struct list_head *head)
20350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
20450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	return head->next == head;
20550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
20650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
20750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
20850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_empty_careful - tests whether a list is empty and not being modified
20950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the list to test
21050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
21150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Description:
21250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * tests whether a list is empty _and_ checks that no other CPU might be
21350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * in the process of modifying either member (next or prev)
21450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
21550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * NOTE: using list_empty_careful() without synchronization
21650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * can only be safe if the only activity that can happen
21750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * to the list entry is list_del_init(). Eg. it cannot be used
21850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * if another CPU could re-list_add() it.
21950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
22050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline int list_empty_careful(const struct list_head *head)
22150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
22250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head *next = head->next;
22350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	return (next == head) && (next == head->prev);
22450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
22550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
22650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
22750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_is_singular - tests whether a list has just one entry.
22850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the list to test.
22950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
23050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline int list_is_singular(const struct list_head *head)
23150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
23250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	return !list_empty(head) && (head->next == head->prev);
23350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
23450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
23550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void __list_cut_position(struct list_head *list,
236689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				       struct list_head *head,
237689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				       struct list_head *entry)
23850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
23950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head *new_first = entry->next;
24050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list->next = head->next;
24150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list->next->prev = list;
24250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list->prev = entry;
24350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	entry->next = list;
24450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	head->next = new_first;
24550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	new_first->prev = head;
24650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
24750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
24850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
24950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_cut_position - cut a list into two
25050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: a new list to add all removed entries
25150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: a list with entries
25250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @entry: an entry within head, could be the head itself
25350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *	and if so we won't cut the list
25450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
25550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * This helper moves the initial part of @head, up to and
25650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * including @entry, from @head to @list. You should
25750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * pass on @entry an element you know is on @head. @list
25850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * should be an empty list or a list you do not care about
25950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * losing its data.
26050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
26150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
26250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_cut_position(struct list_head *list,
263689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				     struct list_head *head,
264689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				     struct list_head *entry)
26550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
26650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (list_empty(head))
26750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		return;
268689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (list_is_singular(head) && (head->next != entry && head != entry))
26950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		return;
27050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (entry == head)
27150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		INIT_LIST_HEAD(list);
27250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	else
27350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		__list_cut_position(list, head, entry);
27450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
27550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
27650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void __list_splice(const struct list_head *list,
277689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				 struct list_head *prev, struct list_head *next)
27850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
27950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head *first = list->next;
28050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	struct list_head *last = list->prev;
28150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
28250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	first->prev = prev;
28350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	prev->next = first;
28450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
28550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	last->next = next;
28650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	next->prev = last;
28750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
28850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
28950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
29050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_splice - join two lists, this is designed for stacks
29150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the new list to add.
29250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the place to add it in the first list.
29350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
29450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_splice(const struct list_head *list,
295689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			       struct list_head *head)
29650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
29750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (!list_empty(list))
29850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		__list_splice(list, head, head->next);
29950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
30050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
30150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
30250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_splice_tail - join two lists, each list being a queue
30350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the new list to add.
30450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the place to add it in the first list.
30550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
30650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_splice_tail(struct list_head *list,
307689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				    struct list_head *head)
30850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
30950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (!list_empty(list))
31050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		__list_splice(list, head->prev, head);
31150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
31250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
31350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
31450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_splice_init - join two lists and reinitialise the emptied list.
31550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the new list to add.
31650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the place to add it in the first list.
31750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
31850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * The list at @list is reinitialised
31950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
32050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_splice_init(struct list_head *list,
32150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie				    struct list_head *head)
32250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
32350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (!list_empty(list)) {
32450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		__list_splice(list, head, head->next);
32550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		INIT_LIST_HEAD(list);
32650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	}
32750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
32850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
32950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
33050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_splice_tail_init - join two lists and reinitialise the emptied list
33150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @list: the new list to add.
33250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head: the place to add it in the first list.
33350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
33450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Each of the lists is a queue.
33550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * The list at @list is reinitialised
33650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
33750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic inline void list_splice_tail_init(struct list_head *list,
33850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie					 struct list_head *head)
33950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
34050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	if (!list_empty(list)) {
34150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		__list_splice(list, head->prev, head);
34250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		INIT_LIST_HEAD(list);
34350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	}
34450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
34550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
34650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
34750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_entry - get the struct for this entry
34850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @ptr:	the &struct list_head pointer.
34950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @type:	the type of the struct this is embedded in.
35050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
35150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
35250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_entry(ptr, type, member) \
35350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	container_of(ptr, type, member)
35450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
35550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
35650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_first_entry - get the first element from a list
35750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @ptr:	the list head to take the element from.
35850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @type:	the type of the struct this is embedded in.
35950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
36050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
36150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Note, that list is expected to be not empty.
36250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
36350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_first_entry(ptr, type, member) \
36450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	list_entry((ptr)->next, type, member)
36550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
36650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
36750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each	-	iterate over a list
36850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the &struct list_head to use as a loop cursor.
36950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
37050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
37150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each(pos, head) \
37250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
373689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		pos = pos->next)
37450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
37550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
37650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_prev	-	iterate over a list backwards
37750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the &struct list_head to use as a loop cursor.
37850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
37950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
38050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_prev(pos, head) \
38150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
382689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		pos = pos->prev)
38350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
38450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
38550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_safe - iterate over a list safe against removal of list entry
38650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the &struct list_head to use as a loop cursor.
38750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another &struct list_head to use as temporary storage
38850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
38950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
39050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_safe(pos, n, head) \
39150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = (head)->next, n = pos->next; pos != (head); \
39250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		pos = n, n = pos->next)
39350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
39450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
39550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
39650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the &struct list_head to use as a loop cursor.
39750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another &struct list_head to use as temporary storage
39850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
39950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
40050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_prev_safe(pos, n, head) \
40150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = (head)->prev, n = pos->prev; \
40250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     prefetch(pos->prev), pos != (head); \
40350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = n, n = pos->prev)
40450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
40550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
40650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry	-	iterate over list of given type
40750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
40850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
40950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
41050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
41150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry(pos, head, member)				\
41250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry((head)->next, typeof(*pos), member);	\
41350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     &pos->member != (head); 	\
41450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = list_entry(pos->member.next, typeof(*pos), member))
41550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
41650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
41750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_reverse - iterate backwards over list of given type.
41850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
41950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
42050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
42150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
42250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_reverse(pos, head, member)			\
42350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
42450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     prefetch(pos->member.prev), &pos->member != (head); 	\
42550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = list_entry(pos->member.prev, typeof(*pos), member))
42650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
42750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
42850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
42950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a start point
43050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head of the list
43150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
43250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
43350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
43450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
43550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_prepare_entry(pos, head, member) \
43650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	((pos) ? : list_entry(head, typeof(*pos), member))
43750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
43850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
43950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_continue - continue iteration over list of given type
44050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
44150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
44250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
44350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
44450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Continue to iterate over list of given type, continuing after
44550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * the current position.
44650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
44750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_continue(pos, head, member) 		\
44850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
44950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     prefetch(pos->member.next), &pos->member != (head);	\
45050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = list_entry(pos->member.next, typeof(*pos), member))
45150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
45250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
45350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_continue_reverse - iterate backwards from the given point
45450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
45550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
45650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
45750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
45850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Start to iterate over list of given type backwards, continuing after
45950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * the current position.
46050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
46150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_continue_reverse(pos, head, member)		\
46250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
46350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     prefetch(pos->member.prev), &pos->member != (head);	\
46450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = list_entry(pos->member.prev, typeof(*pos), member))
46550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
46650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
46750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_from - iterate over list of given type from the current point
46850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
46950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
47050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
47150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
47250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Iterate over list of given type, continuing from current position.
47350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
47450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_from(pos, head, member) 			\
47550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (; prefetch(pos->member.next), &pos->member != (head);	\
47650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = list_entry(pos->member.next, typeof(*pos), member))
47750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
47850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
47950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
48050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
48150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another type * to use as temporary storage
48250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
48350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
48450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
48550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_safe(pos, n, head, member)			\
48650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry((head)->next, typeof(*pos), member),	\
48750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		n = list_entry(pos->member.next, typeof(*pos), member);	\
48850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     &pos->member != (head); 					\
48950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
49050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
49150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
49250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_safe_continue
49350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
49450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another type * to use as temporary storage
49550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
49650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
49750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
49850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Iterate over list of given type, continuing after current point,
49950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * safe against removal of list entry.
50050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
50150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
50250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
50350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		n = list_entry(pos->member.next, typeof(*pos), member);		\
50450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     &pos->member != (head);						\
50550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
50650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
50750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
50850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_safe_from
50950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
51050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another type * to use as temporary storage
51150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
51250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
51350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
51450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Iterate over list of given type from current point, safe against
51550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * removal of list entry.
51650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
51750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_safe_from(pos, n, head, member) 			\
51850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
51950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     &pos->member != (head);						\
52050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
52150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
52250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie/**
52350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * list_for_each_entry_safe_reverse
52450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @pos:	the type * to use as a loop cursor.
52550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @n:		another type * to use as temporary storage
52650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @head:	the head for your list.
52750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * @member:	the name of the list_struct within the struct.
52850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie *
52950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * Iterate backwards over list of given type, safe against removal
53050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie * of list entry.
53150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie */
53250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
53350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
53450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie		n = list_entry(pos->member.prev, typeof(*pos), member);	\
53550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     &pos->member != (head); 					\
53650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
53750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
53850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestruct offset {
539689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct list_head list;
540689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned offset;
54150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie};
54250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
54350f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestruct table {
544689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct list_head offsets;
545689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned offset_max;
546689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned nentry;
547689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned *table;
548689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	char *gpu_prefix;
54950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie};
55050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5510592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic struct offset *offset_new(unsigned o)
55250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
553689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct offset *offset;
554689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
555689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	offset = (struct offset *)malloc(sizeof(struct offset));
556689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (offset) {
557689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		INIT_LIST_HEAD(&offset->list);
558689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		offset->offset = o;
559689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
560689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	return offset;
56150f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
56250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5630592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic void table_offset_add(struct table *t, struct offset *offset)
56450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
565689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	list_add_tail(&offset->list, &t->offsets);
56650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
56750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5680592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic void table_init(struct table *t)
56950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
570689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	INIT_LIST_HEAD(&t->offsets);
571689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->offset_max = 0;
572689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->nentry = 0;
573689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->table = NULL;
57450f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
57550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
5760592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic void table_print(struct table *t)
57750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
578689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned nlloop, i, j, n, c, id;
579689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
580689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	nlloop = (t->nentry + 3) / 4;
581689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	c = t->nentry;
582689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
583689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	       t->nentry);
584689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	for (i = 0, id = 0; i < nlloop; i++) {
585689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		n = 4;
586689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		if (n > c)
587689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			n = c;
588689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		c -= n;
589689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		for (j = 0; j < n; j++) {
590689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			if (j == 0)
591689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				printf("\t");
592689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			else
593689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				printf(" ");
594689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			printf("0x%08X,", t->table[id++]);
595689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		}
596689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		printf("\n");
597689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
598689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	printf("};\n");
59950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
60050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
6010592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic int table_build(struct table *t)
60250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
603689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct offset *offset;
604689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned i, m;
605689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
606689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->nentry = ((t->offset_max >> 2) + 31) / 32;
607689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
608689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (t->table == NULL)
609689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		return -1;
610689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
611689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	list_for_each_entry(offset, &t->offsets, list) {
612689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		i = (offset->offset >> 2) / 32;
613689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		m = (offset->offset >> 2) & 31;
614689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		m = 1 << m;
615689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		t->table[i] ^= m;
616689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
617689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	return 0;
61850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
61950f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
62050f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airliestatic char gpu_name[10];
6210592e4c49e5af8ef71a1aa9308a100d711c64911Josh Triplettstatic int parser_auth(struct table *t, const char *filename)
62250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
623689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	FILE *file;
624689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	regex_t mask_rex;
625689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	regmatch_t match[4];
626689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	char buf[1024];
627689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	size_t end;
628689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	int len;
629689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	int done = 0;
630689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	int r;
631689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	unsigned o;
632689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct offset *offset;
633689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	char last_reg_s[10];
634689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	int last_reg;
635689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
636689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (regcomp
637689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	    (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
638689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		fprintf(stderr, "Failed to compile regular expression\n");
639689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		return -1;
640689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
641689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	file = fopen(filename, "r");
642689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (file == NULL) {
643689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		fprintf(stderr, "Failed to open: %s\n", filename);
644689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		return -1;
645689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
646689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	fseek(file, 0, SEEK_END);
647689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	end = ftell(file);
648689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	fseek(file, 0, SEEK_SET);
649689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
650689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	/* get header */
651059d233f9c1183ed2f59d631e4daf486060e880dAlexander Beregalov	if (fgets(buf, 1024, file) == NULL) {
652059d233f9c1183ed2f59d631e4daf486060e880dAlexander Beregalov		fclose(file);
653689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		return -1;
654059d233f9c1183ed2f59d631e4daf486060e880dAlexander Beregalov	}
655689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
656689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	/* first line will contain the last register
657689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	 * and gpu name */
6586b6419005ef1590f4f532899222424b4539b0511Alan	sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
659689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	t->gpu_prefix = gpu_name;
660689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	last_reg = strtol(last_reg_s, NULL, 16);
661689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
662689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	do {
663e917fd39eb35e5b2c464e67a80e759f3eb468e48Jesper Juhl		if (fgets(buf, 1024, file) == NULL) {
664e917fd39eb35e5b2c464e67a80e759f3eb468e48Jesper Juhl			fclose(file);
665689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			return -1;
666e917fd39eb35e5b2c464e67a80e759f3eb468e48Jesper Juhl		}
667689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		len = strlen(buf);
668689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		if (ftell(file) == end)
669689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			done = 1;
670689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		if (len) {
671689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			r = regexec(&mask_rex, buf, 4, match, 0);
672689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			if (r == REG_NOMATCH) {
673689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			} else if (r) {
674689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				fprintf(stderr,
675689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie					"Error matching regular expression %d in %s\n",
676689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie					r, filename);
677e917fd39eb35e5b2c464e67a80e759f3eb468e48Jesper Juhl				fclose(file);
678689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				return -1;
679689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			} else {
680689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				buf[match[0].rm_eo] = 0;
681689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				buf[match[1].rm_eo] = 0;
682689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				buf[match[2].rm_eo] = 0;
683689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				o = strtol(&buf[match[1].rm_so], NULL, 16);
684689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				offset = offset_new(o);
685689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				table_offset_add(t, offset);
686689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie				if (o > t->offset_max)
687689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie					t->offset_max = o;
688689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie			}
689689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		}
690689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	} while (!done);
691689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	fclose(file);
692689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (t->offset_max < last_reg)
693689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		t->offset_max = last_reg;
694689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	return table_build(t);
69550f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
69650f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie
69750f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlieint main(int argc, char *argv[])
69850f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie{
699689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	struct table t;
700689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie
701689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (argc != 2) {
702689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
703689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		exit(1);
704689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
705689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	table_init(&t);
706689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	if (parser_auth(&t, argv[1])) {
707689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		fprintf(stderr, "Failed to parse file %s\n", argv[1]);
708689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie		return -1;
709689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	}
710689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	table_print(&t);
711689d7c2a1127378854c7d7ea8d7c81238a824240Dave Airlie	return 0;
71250f153036c9d9e4ae1768d5ca9c2ad4184f7a0b7Dave Airlie}
713