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 */
49genlist_entry_t *
50add_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 */
79void 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 */
104genlist_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 */
122void 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
135bool 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 */
146void 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