1 /*
2  * mr_sas_list.h: header for mr_sas
3  *
4  * Solaris MegaRAID driver for SAS2.0 controllers
5  * Copyright (c) 2008-2012, LSI Logic Corporation.
6  * All rights reserved.
7  */
8 
9 /* Copyright 2012 Nexenta Systems, Inc. All rights reserved. */
10 
11 /*
12  * Extract C functions from LSI-provided mr_sas_list.h such that we can both
13  * be lint-clean and provide a slightly better source organizational model
14  * beyond preprocessor abuse.
15  */
16 
17 #include "mr_sas_list.h"
18 
19 /*
20  * Insert a new entry between two known consecutive entries.
21  *
22  * This is only for internal list manipulation where we know
23  * the prev/next entries already!
24  */
25 static inline void
__list_add(struct mlist_head * new,struct mlist_head * prev,struct mlist_head * next)26 __list_add(struct mlist_head *new, struct mlist_head *prev,
27     struct mlist_head *next)
28 {
29 	next->prev = new;
30 	new->next = next;
31 	new->prev = prev;
32 	prev->next = new;
33 }
34 
35 /*
36  * mlist_add - add a new entry
37  * @new: new entry to be added
38  * @head: list head to add it after
39  *
40  * Insert a new entry after the specified head.
41  * This is good for implementing stacks.
42  */
43 void
mlist_add(struct mlist_head * new,struct mlist_head * head)44 mlist_add(struct mlist_head *new, struct mlist_head *head)
45 {
46 	__list_add(new, head, head->next);
47 }
48 
49 /*
50  * mlist_add_tail - add a new entry
51  * @new: new entry to be added
52  * @head: list head to add it before
53  *
54  * Insert a new entry before the specified head.
55  * This is useful for implementing queues.
56  */
57 void
mlist_add_tail(struct mlist_head * new,struct mlist_head * head)58 mlist_add_tail(struct mlist_head *new, struct mlist_head *head)
59 {
60 	__list_add(new, head->prev, head);
61 }
62 
63 /*
64  * Delete a list entry by making the prev/next entries
65  * point to each other.
66  *
67  * This is only for internal list manipulation where we know
68  * the prev/next entries already!
69  */
70 static inline void
__list_del(struct mlist_head * prev,struct mlist_head * next)71 __list_del(struct mlist_head *prev, struct mlist_head *next)
72 {
73 	next->prev = prev;
74 	prev->next = next;
75 }
76 
77 /*
78  * mlist_del_init - deletes entry from list and reinitialize it.
79  * @entry: the element to delete from the list.
80  */
81 void
mlist_del_init(struct mlist_head * entry)82 mlist_del_init(struct mlist_head *entry)
83 {
84 	__list_del(entry->prev, entry->next);
85 	INIT_LIST_HEAD(entry);
86 }
87 
88 /*
89  * mlist_empty - tests whether a list is empty
90  * @head: the list to test.
91  */
92 int
mlist_empty(struct mlist_head * head)93 mlist_empty(struct mlist_head *head)
94 {
95 	return (head->next == head);
96 }
97 
98 /*
99  * mlist_splice - join two lists
100  * @list: the new list to add.
101  * @head: the place to add it in the first list.
102  */
103 void
mlist_splice(struct mlist_head * list,struct mlist_head * head)104 mlist_splice(struct mlist_head *list, struct mlist_head *head)
105 {
106 	struct mlist_head *first = list->next;
107 
108 	if (first != list) {
109 		struct mlist_head *last = list->prev;
110 		struct mlist_head *at = head->next;
111 
112 		first->prev = head;
113 		head->next = first;
114 
115 		last->next = at;
116 		at->prev = last;
117 	}
118 }
119