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 */
25static inline void
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 */
43void
44mlist_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 */
57void
58mlist_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 */
70static inline void
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 */
81void
82mlist_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 */
92int
93mlist_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 */
103void
104mlist_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