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