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