1235783Skib/* drm_linux_list.h -- linux list functions for the BSDs. 2235783Skib * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org 3235783Skib */ 4235783Skib/*- 5235783Skib * Copyright 2003 Eric Anholt 6235783Skib * All Rights Reserved. 7235783Skib * 8235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 9235783Skib * copy of this software and associated documentation files (the "Software"), 10235783Skib * to deal in the Software without restriction, including without limitation 11235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12235783Skib * and/or sell copies of the Software, and to permit persons to whom the 13235783Skib * Software is furnished to do so, subject to the following conditions: 14235783Skib * 15235783Skib * The above copyright notice and this permission notice (including the next 16235783Skib * paragraph) shall be included in all copies or substantial portions of the 17235783Skib * Software. 18235783Skib * 19235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22235783Skib * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23235783Skib * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24235783Skib * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25235783Skib * OTHER DEALINGS IN THE SOFTWARE. 26235783Skib * 27235783Skib * Authors: 28235783Skib * Eric Anholt <anholt@FreeBSD.org> 29235783Skib * 30235783Skib */ 31235783Skib 32235783Skib#include <sys/cdefs.h> 33235783Skib__FBSDID("$FreeBSD$"); 34235783Skib 35235783Skib#ifndef _DRM_LINUX_LIST_H_ 36235783Skib#define _DRM_LINUX_LIST_H_ 37235783Skib 38235783Skibstruct list_head { 39235783Skib struct list_head *next, *prev; 40235783Skib}; 41235783Skib 42235783Skib#define list_entry(ptr, type, member) container_of(ptr,type,member) 43235783Skib 44235783Skibstatic __inline__ void 45235783SkibINIT_LIST_HEAD(struct list_head *head) { 46235783Skib (head)->next = head; 47235783Skib (head)->prev = head; 48235783Skib} 49235783Skib 50235783Skib#define LIST_HEAD_INIT(name) { &(name), &(name) } 51235783Skib 52235783Skib#define DRM_LIST_HEAD(name) \ 53235783Skib struct list_head name = LIST_HEAD_INIT(name) 54235783Skib 55235783Skibstatic __inline__ int 56235783Skiblist_empty(const struct list_head *head) { 57235783Skib return (head)->next == head; 58235783Skib} 59235783Skib 60235783Skibstatic __inline__ void 61235783Skiblist_add(struct list_head *new, struct list_head *head) { 62235783Skib (head)->next->prev = new; 63235783Skib (new)->next = (head)->next; 64235783Skib (new)->prev = head; 65235783Skib (head)->next = new; 66235783Skib} 67235783Skib 68235783Skibstatic __inline__ void 69235783Skiblist_add_tail(struct list_head *entry, struct list_head *head) { 70235783Skib (entry)->prev = (head)->prev; 71235783Skib (entry)->next = head; 72235783Skib (head)->prev->next = entry; 73235783Skib (head)->prev = entry; 74235783Skib} 75235783Skib 76235783Skibstatic __inline__ void 77235783Skiblist_del(struct list_head *entry) { 78235783Skib (entry)->next->prev = (entry)->prev; 79235783Skib (entry)->prev->next = (entry)->next; 80235783Skib} 81235783Skib 82235783Skibstatic inline void list_replace(struct list_head *old, 83235783Skib struct list_head *new) 84235783Skib{ 85235783Skib new->next = old->next; 86235783Skib new->next->prev = new; 87235783Skib new->prev = old->prev; 88235783Skib new->prev->next = new; 89235783Skib} 90235783Skib 91235783Skibstatic inline void list_move(struct list_head *list, struct list_head *head) 92235783Skib{ 93235783Skib list_del(list); 94235783Skib list_add(list, head); 95235783Skib} 96235783Skib 97235783Skibstatic inline void list_move_tail(struct list_head *list, 98235783Skib struct list_head *head) 99235783Skib{ 100235783Skib list_del(list); 101235783Skib list_add_tail(list, head); 102235783Skib} 103235783Skib 104235783Skibstatic __inline__ void 105235783Skiblist_del_init(struct list_head *entry) { 106235783Skib (entry)->next->prev = (entry)->prev; 107235783Skib (entry)->prev->next = (entry)->next; 108235783Skib INIT_LIST_HEAD(entry); 109235783Skib} 110235783Skib 111235783Skib#define list_for_each(entry, head) \ 112235783Skib for (entry = (head)->next; entry != head; entry = (entry)->next) 113235783Skib 114235783Skib#define list_for_each_prev(entry, head) \ 115235783Skib for (entry = (head)->prev; entry != (head); \ 116235783Skib entry = entry->prev) 117235783Skib 118235783Skib#define list_for_each_safe(entry, temp, head) \ 119235783Skib for (entry = (head)->next, temp = (entry)->next; \ 120235783Skib entry != head; \ 121235783Skib entry = temp, temp = entry->next) 122235783Skib 123235783Skib#define list_for_each_entry(pos, head, member) \ 124235783Skib for (pos = list_entry((head)->next, __typeof(*pos), member); \ 125235783Skib &pos->member != (head); \ 126235783Skib pos = list_entry(pos->member.next, __typeof(*pos), member)) 127235783Skib 128235783Skib#define list_for_each_entry_continue_reverse(pos, head, member) \ 129235783Skib for (pos = list_entry(pos->member.prev, __typeof(*pos), member); \ 130235783Skib &pos->member != (head); \ 131235783Skib pos = list_entry(pos->member.prev, __typeof(*pos), member)) 132235783Skib 133235783Skib/** 134235783Skib * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 135235783Skib * @pos: the type * to use as a loop cursor. 136235783Skib * @n: another type * to use as temporary storage 137235783Skib * @head: the head for your list. 138235783Skib * @member: the name of the list_struct within the struct. 139235783Skib */ 140235783Skib#define list_for_each_entry_safe(pos, n, head, member) \ 141235783Skib for (pos = list_entry((head)->next, __typeof(*pos), member), \ 142235783Skib n = list_entry(pos->member.next, __typeof(*pos), member); \ 143235783Skib &pos->member != (head); \ 144235783Skib pos = n, n = list_entry(n->member.next, __typeof(*n), member)) 145235783Skib 146254841Sdumbbell#define list_for_each_entry_safe_from(pos, n, head, member) \ 147254841Sdumbbell for (n = list_entry(pos->member.next, __typeof(*pos), member); \ 148254841Sdumbbell &pos->member != (head); \ 149254841Sdumbbell pos = n, n = list_entry(n->member.next, __typeof(*n), member)) 150254841Sdumbbell 151235783Skib#define list_first_entry(ptr, type, member) \ 152235783Skib list_entry((ptr)->next, type, member) 153235783Skib 154235783Skib 155235783Skibstatic inline void 156235783Skib__list_splice(const struct list_head *list, struct list_head *prev, 157235783Skib struct list_head *next) 158235783Skib{ 159235783Skib struct list_head *first = list->next; 160235783Skib struct list_head *last = list->prev; 161235783Skib 162235783Skib first->prev = prev; 163235783Skib prev->next = first; 164235783Skib 165235783Skib last->next = next; 166235783Skib next->prev = last; 167235783Skib} 168235783Skib 169235783Skibstatic inline void 170235783Skiblist_splice(const struct list_head *list, struct list_head *head) 171235783Skib{ 172235783Skib if (list_empty(list)) 173235783Skib return; 174235783Skib 175235783Skib __list_splice(list, head, head->next); 176235783Skib} 177235783Skib 178235783Skibvoid drm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, 179235783Skib struct list_head *a, struct list_head *b)); 180235783Skib 181296548Sdumbbell/* hlist, copied from sys/dev/ofed/linux/list.h */ 182296548Sdumbbell 183296548Sdumbbellstruct hlist_head { 184296548Sdumbbell struct hlist_node *first; 185296548Sdumbbell}; 186296548Sdumbbell 187296548Sdumbbellstruct hlist_node { 188296548Sdumbbell struct hlist_node *next, **pprev; 189296548Sdumbbell}; 190296548Sdumbbell 191296548Sdumbbell#define HLIST_HEAD_INIT { } 192296548Sdumbbell#define HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT 193296548Sdumbbell#define INIT_HLIST_HEAD(head) (head)->first = NULL 194296548Sdumbbell#define INIT_HLIST_NODE(node) \ 195296548Sdumbbelldo { \ 196296548Sdumbbell (node)->next = NULL; \ 197296548Sdumbbell (node)->pprev = NULL; \ 198296548Sdumbbell} while (0) 199296548Sdumbbell 200296548Sdumbbellstatic inline int 201296548Sdumbbellhlist_unhashed(const struct hlist_node *h) 202296548Sdumbbell{ 203296548Sdumbbell 204296548Sdumbbell return !h->pprev; 205296548Sdumbbell} 206296548Sdumbbell 207296548Sdumbbellstatic inline int 208296548Sdumbbellhlist_empty(const struct hlist_head *h) 209296548Sdumbbell{ 210296548Sdumbbell 211296548Sdumbbell return !h->first; 212296548Sdumbbell} 213296548Sdumbbell 214296548Sdumbbellstatic inline void 215296548Sdumbbellhlist_del(struct hlist_node *n) 216296548Sdumbbell{ 217296548Sdumbbell 218296548Sdumbbell if (n->next) 219296548Sdumbbell n->next->pprev = n->pprev; 220296548Sdumbbell *n->pprev = n->next; 221296548Sdumbbell} 222296548Sdumbbell 223296548Sdumbbellstatic inline void 224296548Sdumbbellhlist_del_init(struct hlist_node *n) 225296548Sdumbbell{ 226296548Sdumbbell 227296548Sdumbbell if (hlist_unhashed(n)) 228296548Sdumbbell return; 229296548Sdumbbell hlist_del(n); 230296548Sdumbbell INIT_HLIST_NODE(n); 231296548Sdumbbell} 232296548Sdumbbell 233296548Sdumbbellstatic inline void 234296548Sdumbbellhlist_add_head(struct hlist_node *n, struct hlist_head *h) 235296548Sdumbbell{ 236296548Sdumbbell 237296548Sdumbbell n->next = h->first; 238296548Sdumbbell if (h->first) 239296548Sdumbbell h->first->pprev = &n->next; 240296548Sdumbbell h->first = n; 241296548Sdumbbell n->pprev = &h->first; 242296548Sdumbbell} 243296548Sdumbbell 244296548Sdumbbellstatic inline void 245296548Sdumbbellhlist_add_before(struct hlist_node *n, struct hlist_node *next) 246296548Sdumbbell{ 247296548Sdumbbell 248296548Sdumbbell n->pprev = next->pprev; 249296548Sdumbbell n->next = next; 250296548Sdumbbell next->pprev = &n->next; 251296548Sdumbbell *(n->pprev) = n; 252296548Sdumbbell} 253296548Sdumbbell 254296548Sdumbbellstatic inline void 255296548Sdumbbellhlist_add_after(struct hlist_node *n, struct hlist_node *next) 256296548Sdumbbell{ 257296548Sdumbbell 258296548Sdumbbell next->next = n->next; 259296548Sdumbbell n->next = next; 260296548Sdumbbell next->pprev = &n->next; 261296548Sdumbbell if (next->next) 262296548Sdumbbell next->next->pprev = &next->next; 263296548Sdumbbell} 264296548Sdumbbell 265296548Sdumbbellstatic inline void 266296548Sdumbbellhlist_move_list(struct hlist_head *old, struct hlist_head *new) 267296548Sdumbbell{ 268296548Sdumbbell 269296548Sdumbbell new->first = old->first; 270296548Sdumbbell if (new->first) 271296548Sdumbbell new->first->pprev = &new->first; 272296548Sdumbbell old->first = NULL; 273296548Sdumbbell} 274296548Sdumbbell 275296548Sdumbbell#define hlist_entry(ptr, type, field) container_of(ptr, type, field) 276296548Sdumbbell 277296548Sdumbbell#define hlist_for_each(p, head) \ 278296548Sdumbbell for (p = (head)->first; p; p = p->next) 279296548Sdumbbell 280296548Sdumbbell#define hlist_for_each_safe(p, n, head) \ 281296548Sdumbbell for (p = (head)->first; p && ({ n = p->next; 1; }); p = n) 282296548Sdumbbell 283296548Sdumbbell#define hlist_for_each_entry(tp, p, head, field) \ 284296548Sdumbbell for (p = (head)->first; \ 285296548Sdumbbell p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next) 286296548Sdumbbell 287296548Sdumbbell#define hlist_for_each_entry_continue(tp, p, field) \ 288296548Sdumbbell for (p = (p)->next; \ 289296548Sdumbbell p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next) 290296548Sdumbbell 291296548Sdumbbell#define hlist_for_each_entry_from(tp, p, field) \ 292296548Sdumbbell for (; p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next) 293296548Sdumbbell 294296548Sdumbbell#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ 295296548Sdumbbell for (pos = (head)->first; \ 296296548Sdumbbell (pos) != 0 && ({ n = (pos)->next; \ 297296548Sdumbbell tpos = hlist_entry((pos), typeof(*(tpos)), member); 1;}); \ 298296548Sdumbbell pos = (n)) 299296548Sdumbbell 300235783Skib#endif /* _DRM_LINUX_LIST_H_ */ 301