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 * 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 */ 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 */ 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 */ 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 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 */ 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