1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 *
28 * NAME: gen_util.c
29 *
30 * DESC: Generic kernel utility functions
31 *
32 */
33
34 #include <sys/types.h>
35 #include <sys/debug.h>
36 #include <sys/kmem.h>
37 #include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
38
39 /*
40 * Doubly linked per user context IB resource list definitions
41 * Protection must occur * outside of the list.
42 */
43
44 /*
45 * add_genlist()
46 *
47 * Adds the entry to the tail of the list.
48 */
49 genlist_entry_t *
add_genlist(genlist_t * list,uintptr_t data,void * data_context)50 add_genlist(genlist_t *list, uintptr_t data, void *data_context)
51 {
52
53 genlist_entry_t *new_entry;
54
55 new_entry = (genlist_entry_t *)(kmem_zalloc(sizeof (genlist_entry_t),
56 KM_SLEEP));
57
58 if (new_entry != NULL) {
59 new_entry->data_context = data_context;
60 new_entry->data = data;
61 new_entry->next = NULL;
62 new_entry->prev = list->tail;
63
64 if (!list->count) {
65 list->tail = new_entry;
66 list->head = new_entry;
67 } else {
68 list->tail->next = new_entry;
69 list->tail = new_entry;
70 }
71 list->count++;
72 }
73 return (new_entry);
74 }
75
76 /*
77 * delete_genlist() - delete the specified entry from the list.
78 */
delete_genlist(genlist_t * list,genlist_entry_t * entry)79 void delete_genlist(genlist_t *list, genlist_entry_t *entry) {
80
81 ASSERT(entry);
82
83 if (entry->prev) {
84 entry->prev->next = entry->next;
85 } else {
86 list->head = entry->next;
87 }
88
89 if (entry->next) {
90 entry->next->prev = entry->prev;
91 } else {
92 list->tail = entry->prev;
93 }
94
95 list->count--;
96 entry->prev = entry->next = NULL;
97 kmem_free((void *)entry, sizeof (genlist_entry_t));
98 }
99
100 /*
101 * remove_genlist_head() - remove the entry from the list head, but
102 * don't delete it.
103 */
remove_genlist_head(genlist_t * list)104 genlist_entry_t *remove_genlist_head(genlist_t *list) {
105
106 genlist_entry_t *entry = list->head;
107
108 if (list->head) {
109 list->head = list->head->next;
110 list->count--;
111
112 if (!list->head)
113 list->tail = list->head;
114 }
115
116 return (entry);
117 }
118
119 /*
120 * flush_genlist
121 */
flush_genlist(genlist_t * list)122 void flush_genlist(genlist_t *list) {
123
124 genlist_entry_t *entry;
125
126 entry = remove_genlist_head(list);
127
128 while (entry) {
129 kmem_free((void *)entry, sizeof (genlist_entry_t));
130 entry = remove_genlist_head(list);
131 }
132 init_genlist(list);
133 }
134
genlist_empty(genlist_t * list)135 bool genlist_empty(genlist_t *list) {
136
137 if (list->head != NULL)
138 return (FALSE);
139 else
140 return (TRUE);
141 }
142
143 /*
144 * FUNCTION: insert_genlist_tail()
145 */
insert_genlist_tail(genlist_t * list,genlist_entry_t * entry)146 void insert_genlist_tail(genlist_t *list, genlist_entry_t *entry) {
147
148 entry->next = NULL;
149 entry->prev = list->tail;
150
151 if (!list->count) {
152 list->tail = entry;
153 list->head = entry;
154 } else {
155 list->tail->next = entry;
156 list->tail = entry;
157 }
158 list->count++;
159 }
160