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) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * MODULE: dapl_sp_util.c 34 * 35 * PURPOSE: Manage PSP Info structure 36 * 37 * $Id: dapl_sp_util.c,v 1.10 2003/08/20 14:55:39 sjs2 Exp $ 38 */ 39 40 #include "dapl.h" 41 #include "dapl_sp_util.h" 42 43 /* 44 * Local definitions 45 */ 46 47 48 /* 49 * dapl_sp_alloc 50 * 51 * alloc and initialize a PSP INFO struct 52 * 53 * Input: 54 * IA INFO struct ptr 55 * 56 * Output: 57 * sp_ptr 58 * 59 * Returns: 60 * NULL 61 * pointer to sp info struct 62 * 63 */ 64 DAPL_SP * 65 dapls_sp_alloc( 66 IN DAPL_IA *ia_ptr, 67 IN DAT_BOOLEAN is_psp) 68 { 69 DAPL_SP *sp_ptr; 70 71 /* Allocate EP */ 72 sp_ptr = (DAPL_SP *)dapl_os_alloc(sizeof (DAPL_SP)); 73 if (sp_ptr == NULL) { 74 return (NULL); 75 } 76 77 /* zero the structure */ 78 (void) dapl_os_memzero(sp_ptr, sizeof (DAPL_SP)); 79 80 /* 81 * initialize the header 82 */ 83 sp_ptr->header.provider = ia_ptr->header.provider; 84 if (is_psp) { 85 sp_ptr->header.magic = DAPL_MAGIC_PSP; 86 sp_ptr->header.handle_type = DAT_HANDLE_TYPE_PSP; 87 } else { 88 sp_ptr->header.magic = DAPL_MAGIC_RSP; 89 sp_ptr->header.handle_type = DAT_HANDLE_TYPE_RSP; 90 } 91 sp_ptr->header.owner_ia = ia_ptr; 92 sp_ptr->header.user_context.as_64 = 0; 93 sp_ptr->header.user_context.as_ptr = NULL; 94 dapl_llist_init_entry(&sp_ptr->header.ia_list_entry); 95 dapl_os_lock_init(&sp_ptr->header.lock); 96 97 /* 98 * Initialize the Body (set to NULL above) 99 */ 100 dapl_llist_init_head(&sp_ptr->cr_list_head); 101 102 return (sp_ptr); 103 } 104 105 106 /* 107 * dapl_sp_free 108 * 109 * Free the passed in PSP structure. 110 * 111 * Input: 112 * entry point pointer 113 * 114 * Output: 115 * none 116 * 117 * Returns: 118 * none 119 * 120 */ 121 void 122 dapls_sp_free_sp( 123 IN DAPL_SP *sp_ptr) 124 { 125 dapl_os_assert(sp_ptr->header.magic == DAPL_MAGIC_PSP || 126 sp_ptr->header.magic == DAPL_MAGIC_RSP); 127 dapl_os_assert(dapl_llist_is_empty(&sp_ptr->cr_list_head)); 128 129 dapl_os_lock(&sp_ptr->header.lock); 130 /* reset magic to prevent reuse */ 131 sp_ptr->header.magic = DAPL_MAGIC_INVALID; 132 dapl_os_unlock(&sp_ptr->header.lock); 133 dapl_os_free(sp_ptr, sizeof (DAPL_SP)); 134 } 135 136 137 /* 138 * dapl_cr_link_cr 139 * 140 * Add a cr to a PSP structure 141 * 142 * Input: 143 * sp_ptr 144 * cr_ptr 145 * 146 * Output: 147 * none 148 * 149 * Returns: 150 * none 151 * 152 */ 153 void 154 dapl_sp_link_cr( 155 IN DAPL_SP *sp_ptr, 156 IN DAPL_CR *cr_ptr) 157 { 158 dapl_os_lock(&sp_ptr->header.lock); 159 dapl_llist_add_tail(&sp_ptr->cr_list_head, 160 &cr_ptr->header.ia_list_entry, cr_ptr); 161 sp_ptr->cr_list_count++; 162 dapl_os_unlock(&sp_ptr->header.lock); 163 } 164 165 166 /* 167 * dapl_sp_search_cr 168 * 169 * Search for a CR on the PSP cr_list with a matching cm_handle. When 170 * found, remove it from the list and update fields. 171 * 172 * Input: 173 * sp_ptr 174 * ib_cm_handle 175 * 176 * Output: 177 * none 178 * 179 * Returns: 180 * cr_ptr_fnd Pointer to matching DAPL_CR 181 * 182 */ 183 DAPL_CR * 184 dapl_sp_search_cr( 185 IN DAPL_SP *sp_ptr, 186 IN ib_cm_handle_t ib_cm_handle) 187 { 188 DAPL_CR *cr_ptr; 189 DAPL_CR *cr_ptr_fnd; 190 191 dapl_os_lock(&sp_ptr->header.lock); 192 cr_ptr_fnd = NULL; 193 cr_ptr = (DAPL_CR *) dapl_llist_peek_head(&sp_ptr->cr_list_head); 194 195 do { 196 if (cr_ptr->ib_cm_handle == ib_cm_handle) { 197 cr_ptr_fnd = cr_ptr; 198 break; 199 } 200 cr_ptr = cr_ptr->header.ia_list_entry.flink->data; 201 } while ((void *)cr_ptr != (void *)sp_ptr->cr_list_head->data); 202 203 dapl_os_unlock(&sp_ptr->header.lock); 204 return (cr_ptr_fnd); 205 } 206 207 208 209 /* 210 * dapl_sp_remove_cr 211 * 212 * Remove the CR from the PSP. Done prior to freeing the CR resource. 213 * 214 * Input: 215 * sp_ptr 216 * cr_ptr 217 * 218 * Output: 219 * none 220 * 221 * Returns: 222 * void 223 * 224 */ 225 void 226 dapl_sp_remove_cr( 227 IN DAPL_SP *sp_ptr, 228 IN DAPL_CR *cr_ptr) 229 { 230 dapl_os_lock(&sp_ptr->header.lock); 231 232 if (dapl_llist_is_empty(&sp_ptr->cr_list_head)) { 233 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 234 "***dapl_sp_remove_cr: removing from empty queue! sp %p\n", 235 sp_ptr); 236 dapl_os_unlock(&sp_ptr->header.lock); 237 return; 238 } 239 240 (void) dapl_llist_remove_entry(&sp_ptr->cr_list_head, 241 &cr_ptr->header.ia_list_entry); 242 sp_ptr->cr_list_count--; 243 244 dapl_os_unlock(&sp_ptr->header.lock); 245 } 246