1*2eeaed14Srobj /*
2*2eeaed14Srobj  * CDDL HEADER START
3*2eeaed14Srobj  *
4*2eeaed14Srobj  * The contents of this file are subject to the terms of the
5*2eeaed14Srobj  * Common Development and Distribution License (the "License").
6*2eeaed14Srobj  * You may not use this file except in compliance with the License.
7*2eeaed14Srobj  *
8*2eeaed14Srobj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2eeaed14Srobj  * or http://www.opensolaris.org/os/licensing.
10*2eeaed14Srobj  * See the License for the specific language governing permissions
11*2eeaed14Srobj  * and limitations under the License.
12*2eeaed14Srobj  *
13*2eeaed14Srobj  * When distributing Covered Code, include this CDDL HEADER in each
14*2eeaed14Srobj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2eeaed14Srobj  * If applicable, add the following below this CDDL HEADER, with the
16*2eeaed14Srobj  * fields enclosed by brackets "[]" replaced with your own identifying
17*2eeaed14Srobj  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2eeaed14Srobj  *
19*2eeaed14Srobj  * CDDL HEADER END
20*2eeaed14Srobj  */
21*2eeaed14Srobj /*
22*2eeaed14Srobj  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*2eeaed14Srobj  * Use is subject to license terms.
24*2eeaed14Srobj  */
25*2eeaed14Srobj 
26*2eeaed14Srobj /*
27*2eeaed14Srobj  * Embedded Linked Lists
28*2eeaed14Srobj  *
29*2eeaed14Srobj  * Simple doubly-linked list implementation.  This implementation assumes that
30*2eeaed14Srobj  * each list element contains an embedded ipmi_list_t (previous and next
31*2eeaed14Srobj  * pointers), which is typically the first member of the element struct.
32*2eeaed14Srobj  * An additional ipmi_list_t is used to store the head (l_next) and tail
33*2eeaed14Srobj  * (l_prev) pointers.  The current head and tail list elements have their
34*2eeaed14Srobj  * previous and next pointers set to NULL, respectively.
35*2eeaed14Srobj  */
36*2eeaed14Srobj 
37*2eeaed14Srobj #include <assert.h>
38*2eeaed14Srobj #include <ipmi_impl.h>
39*2eeaed14Srobj 
40*2eeaed14Srobj void
ipmi_list_append(ipmi_list_t * lp,void * new)41*2eeaed14Srobj ipmi_list_append(ipmi_list_t *lp, void *new)
42*2eeaed14Srobj {
43*2eeaed14Srobj 	ipmi_list_t *p = lp->l_prev;	/* p = tail list element */
44*2eeaed14Srobj 	ipmi_list_t *q = new;		/* q = new list element */
45*2eeaed14Srobj 
46*2eeaed14Srobj 	lp->l_prev = q;
47*2eeaed14Srobj 	q->l_prev = p;
48*2eeaed14Srobj 	q->l_next = NULL;
49*2eeaed14Srobj 
50*2eeaed14Srobj 	if (p != NULL) {
51*2eeaed14Srobj 		assert(p->l_next == NULL);
52*2eeaed14Srobj 		p->l_next = q;
53*2eeaed14Srobj 	} else {
54*2eeaed14Srobj 		assert(lp->l_next == NULL);
55*2eeaed14Srobj 		lp->l_next = q;
56*2eeaed14Srobj 	}
57*2eeaed14Srobj }
58*2eeaed14Srobj 
59*2eeaed14Srobj void
ipmi_list_prepend(ipmi_list_t * lp,void * new)60*2eeaed14Srobj ipmi_list_prepend(ipmi_list_t *lp, void *new)
61*2eeaed14Srobj {
62*2eeaed14Srobj 	ipmi_list_t *p = new;		/* p = new list element */
63*2eeaed14Srobj 	ipmi_list_t *q = lp->l_next;	/* q = head list element */
64*2eeaed14Srobj 
65*2eeaed14Srobj 	lp->l_next = p;
66*2eeaed14Srobj 	p->l_prev = NULL;
67*2eeaed14Srobj 	p->l_next = q;
68*2eeaed14Srobj 
69*2eeaed14Srobj 	if (q != NULL) {
70*2eeaed14Srobj 		assert(q->l_prev == NULL);
71*2eeaed14Srobj 		q->l_prev = p;
72*2eeaed14Srobj 	} else {
73*2eeaed14Srobj 		assert(lp->l_prev == NULL);
74*2eeaed14Srobj 		lp->l_prev = p;
75*2eeaed14Srobj 	}
76*2eeaed14Srobj }
77*2eeaed14Srobj 
78*2eeaed14Srobj void
ipmi_list_insert_before(ipmi_list_t * lp,void * before_me,void * new)79*2eeaed14Srobj ipmi_list_insert_before(ipmi_list_t *lp, void *before_me, void *new)
80*2eeaed14Srobj {
81*2eeaed14Srobj 	ipmi_list_t *p = before_me;
82*2eeaed14Srobj 	ipmi_list_t *q = new;
83*2eeaed14Srobj 
84*2eeaed14Srobj 	if (p == NULL || p->l_prev == NULL) {
85*2eeaed14Srobj 		ipmi_list_prepend(lp, new);
86*2eeaed14Srobj 		return;
87*2eeaed14Srobj 	}
88*2eeaed14Srobj 
89*2eeaed14Srobj 	q->l_prev = p->l_prev;
90*2eeaed14Srobj 	q->l_next = p;
91*2eeaed14Srobj 	p->l_prev = q;
92*2eeaed14Srobj 	q->l_prev->l_next = q;
93*2eeaed14Srobj }
94*2eeaed14Srobj 
95*2eeaed14Srobj void
ipmi_list_insert_after(ipmi_list_t * lp,void * after_me,void * new)96*2eeaed14Srobj ipmi_list_insert_after(ipmi_list_t *lp, void *after_me, void *new)
97*2eeaed14Srobj {
98*2eeaed14Srobj 	ipmi_list_t *p = after_me;
99*2eeaed14Srobj 	ipmi_list_t *q = new;
100*2eeaed14Srobj 
101*2eeaed14Srobj 	if (p == NULL || p->l_next == NULL) {
102*2eeaed14Srobj 		ipmi_list_append(lp, new);
103*2eeaed14Srobj 		return;
104*2eeaed14Srobj 	}
105*2eeaed14Srobj 
106*2eeaed14Srobj 	q->l_next = p->l_next;
107*2eeaed14Srobj 	q->l_prev = p;
108*2eeaed14Srobj 	p->l_next = q;
109*2eeaed14Srobj 	q->l_next->l_prev = q;
110*2eeaed14Srobj }
111*2eeaed14Srobj 
112*2eeaed14Srobj void
ipmi_list_delete(ipmi_list_t * lp,void * existing)113*2eeaed14Srobj ipmi_list_delete(ipmi_list_t *lp, void *existing)
114*2eeaed14Srobj {
115*2eeaed14Srobj 	ipmi_list_t *p = existing;
116*2eeaed14Srobj 
117*2eeaed14Srobj 	if (p->l_prev != NULL)
118*2eeaed14Srobj 		p->l_prev->l_next = p->l_next;
119*2eeaed14Srobj 	else
120*2eeaed14Srobj 		lp->l_next = p->l_next;
121*2eeaed14Srobj 
122*2eeaed14Srobj 	if (p->l_next != NULL)
123*2eeaed14Srobj 		p->l_next->l_prev = p->l_prev;
124*2eeaed14Srobj 	else
125*2eeaed14Srobj 		lp->l_prev = p->l_prev;
126*2eeaed14Srobj }
127