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