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_provider.c 34 * 35 * PURPOSE: Provider function table 36 * Description: DAT Interfaces to this provider 37 * 38 * $Id: dapl_provider.c,v 1.7 2003/08/08 19:42:54 sjs2 Exp $ 39 */ 40 41 #include "dapl_provider.h" 42 43 44 /* 45 * 46 * Global Data 47 * 48 */ 49 50 DAPL_PROVIDER_LIST g_dapl_provider_list; 51 52 53 /* 54 * the function table for this provider 55 */ 56 57 DAT_PROVIDER g_dapl_provider_template = 58 { 59 NULL, 60 0, 61 &dapl_ia_open, 62 &dapl_ia_query, 63 &dapl_ia_close, 64 65 &dapl_set_consumer_context, 66 &dapl_get_consumer_context, 67 &dapl_get_handle_type, 68 69 &dapl_cno_create, 70 &dapl_cno_modify_agent, 71 &dapl_cno_query, 72 &dapl_cno_free, 73 &dapl_cno_wait, 74 75 &dapl_cr_query, 76 &dapl_cr_accept, 77 &dapl_cr_reject, 78 &dapl_cr_handoff, 79 80 &dapl_evd_create, 81 &dapl_evd_query, 82 &dapl_evd_modify_cno, 83 &dapl_evd_enable, 84 &dapl_evd_disable, 85 &dapl_evd_wait, 86 &dapl_evd_resize, 87 &dapl_evd_post_se, 88 &dapl_evd_dequeue, 89 &dapl_evd_free, 90 91 &dapl_ep_create, 92 &dapl_ep_query, 93 &dapl_ep_modify, 94 &dapl_ep_connect, 95 &dapl_ep_dup_connect, 96 &dapl_ep_disconnect, 97 &dapl_ep_post_send, 98 &dapl_ep_post_recv, 99 &dapl_ep_post_rdma_read, 100 &dapl_ep_post_rdma_write, 101 &dapl_ep_get_status, 102 &dapl_ep_free, 103 104 &dapl_lmr_create, 105 &dapl_lmr_query, 106 &dapl_lmr_free, 107 108 &dapl_rmr_create, 109 &dapl_rmr_query, 110 &dapl_rmr_bind, 111 &dapl_rmr_free, 112 113 &dapl_psp_create, 114 &dapl_psp_query, 115 &dapl_psp_free, 116 117 &dapl_rsp_create, 118 &dapl_rsp_query, 119 &dapl_rsp_free, 120 121 &dapl_pz_create, 122 &dapl_pz_query, 123 &dapl_pz_free, 124 125 &dapl_psp_create_any, 126 &dapl_ep_reset, 127 &dapl_evd_set_unwaitable, 128 &dapl_evd_clear_unwaitable, 129 130 &dapl_lmr_sync_rdma_read, 131 &dapl_lmr_sync_rdma_write, 132 133 &dapl_ep_create_with_srq, 134 &dapl_ep_recv_query, 135 &dapl_ep_set_watermark, 136 137 &dapl_srq_create, 138 &dapl_srq_free, 139 &dapl_srq_post_recv, 140 &dapl_srq_query, 141 &dapl_srq_resize, 142 &dapl_srq_set_lw 143 }; 144 145 146 147 /* 148 * 149 * Function Prototypes 150 * 151 */ 152 153 static DAT_BOOLEAN 154 dapl_provider_list_key_cmp( 155 const char *name_a, 156 const char *name_b); 157 158 159 /* 160 * 161 * Function Definitions 162 * 163 */ 164 165 DAT_RETURN 166 dapl_provider_list_create(void) 167 { 168 DAT_RETURN status; 169 170 status = DAT_SUCCESS; 171 172 /* create the head node */ 173 g_dapl_provider_list.head = dapl_os_alloc( 174 sizeof (DAPL_PROVIDER_LIST_NODE)); 175 if (NULL == g_dapl_provider_list.head) { 176 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 177 DAT_RESOURCE_MEMORY); 178 goto bail; 179 } 180 181 (void) dapl_os_memzero(g_dapl_provider_list.head, 182 sizeof (DAPL_PROVIDER_LIST_NODE)); 183 184 /* create the tail node */ 185 g_dapl_provider_list.tail = dapl_os_alloc( 186 sizeof (DAPL_PROVIDER_LIST_NODE)); 187 if (NULL == g_dapl_provider_list.tail) { 188 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 189 DAT_RESOURCE_MEMORY); 190 goto bail; 191 } 192 193 (void) dapl_os_memzero(g_dapl_provider_list.tail, 194 sizeof (DAPL_PROVIDER_LIST_NODE)); 195 196 g_dapl_provider_list.head->next = g_dapl_provider_list.tail; 197 g_dapl_provider_list.tail->prev = g_dapl_provider_list.head; 198 g_dapl_provider_list.size = 0; 199 200 bail: 201 if (DAT_SUCCESS != status) { 202 if (NULL != g_dapl_provider_list.head) { 203 dapl_os_free(g_dapl_provider_list.head, 204 sizeof (DAPL_PROVIDER_LIST_NODE)); 205 } 206 207 if (NULL != g_dapl_provider_list.tail) { 208 dapl_os_free(g_dapl_provider_list.tail, 209 sizeof (DAPL_PROVIDER_LIST_NODE)); 210 } 211 } 212 213 return (status); 214 } 215 216 217 DAT_RETURN 218 dapl_provider_list_destroy(void) 219 { 220 DAPL_PROVIDER_LIST_NODE *cur_node; 221 222 while (NULL != g_dapl_provider_list.head) { 223 cur_node = g_dapl_provider_list.head; 224 g_dapl_provider_list.head = cur_node->next; 225 226 dapl_os_free(cur_node, sizeof (DAPL_PROVIDER_LIST_NODE)); 227 } 228 229 return (DAT_SUCCESS); 230 } 231 232 233 DAT_COUNT 234 dapl_provider_list_size(void) 235 { 236 return (g_dapl_provider_list.size); 237 } 238 239 240 DAT_RETURN 241 dapl_provider_list_insert( 242 IN const char *name, 243 IN DAT_PROVIDER **p_data) 244 { 245 DAPL_PROVIDER_LIST_NODE *cur_node, *prev_node, *next_node; 246 DAT_RETURN status; 247 unsigned int len; 248 249 status = DAT_SUCCESS; 250 *p_data = NULL; 251 252 cur_node = dapl_os_alloc(sizeof (DAPL_PROVIDER_LIST_NODE)); 253 254 if (NULL == cur_node) { 255 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 256 DAT_RESOURCE_MEMORY); 257 goto bail; 258 } 259 260 len = dapl_os_strlen(name); 261 262 if (DAT_NAME_MAX_LENGTH <= len) { 263 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 264 DAT_RESOURCE_MEMORY); 265 goto bail; 266 } 267 268 /* insert node at end of list to preserve registration order */ 269 prev_node = g_dapl_provider_list.tail->prev; 270 next_node = g_dapl_provider_list.tail; 271 272 (void) dapl_os_memcpy(cur_node->name, name, len); 273 cur_node->name[len] = '\0'; 274 cur_node->data = g_dapl_provider_template; 275 cur_node->data.device_name = cur_node->name; 276 cur_node->next = next_node; 277 cur_node->prev = prev_node; 278 279 prev_node->next = cur_node; 280 next_node->prev = cur_node; 281 282 g_dapl_provider_list.size++; 283 284 if (NULL != p_data) { 285 *p_data = &cur_node->data; 286 } 287 288 bail: 289 if (DAT_SUCCESS != status) { 290 if (NULL != cur_node) { 291 dapl_os_free(cur_node, 292 sizeof (DAPL_PROVIDER_LIST_NODE)); 293 } 294 } 295 296 return (status); 297 } 298 299 300 DAT_RETURN 301 dapl_provider_list_search( 302 IN const char *name, 303 OUT DAT_PROVIDER **p_data) 304 { 305 DAPL_PROVIDER_LIST_NODE *cur_node; 306 DAT_RETURN status; 307 308 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0); 309 310 for (cur_node = g_dapl_provider_list.head->next; 311 g_dapl_provider_list.tail != cur_node; 312 cur_node = cur_node->next) { 313 if (dapl_provider_list_key_cmp(cur_node->name, name)) { 314 if (NULL != p_data) { 315 *p_data = &cur_node->data; 316 } 317 318 status = DAT_SUCCESS; 319 goto bail; 320 } 321 } 322 323 bail: 324 return (status); 325 } 326 327 328 DAT_RETURN 329 dapl_provider_list_remove( 330 IN const char *name) 331 { 332 DAPL_PROVIDER_LIST_NODE *cur_node, *prev_node, *next_node; 333 DAT_RETURN status; 334 335 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0); 336 337 for (cur_node = g_dapl_provider_list.head->next; 338 g_dapl_provider_list.tail != cur_node; 339 cur_node = cur_node->next) { 340 if (dapl_provider_list_key_cmp(cur_node->name, name)) { 341 prev_node = cur_node->prev; 342 next_node = cur_node->next; 343 344 prev_node->next = next_node; 345 next_node->prev = prev_node; 346 347 dapl_os_free(cur_node, 348 sizeof (DAPL_PROVIDER_LIST_NODE)); 349 350 g_dapl_provider_list.size--; 351 352 status = DAT_SUCCESS; 353 goto bail; 354 } 355 } 356 357 bail: 358 return (status); 359 } 360 361 362 DAT_BOOLEAN 363 dapl_provider_list_key_cmp( 364 const char *name_a, 365 const char *name_b) 366 { 367 unsigned int len; 368 369 len = dapl_os_strlen(name_a); 370 371 if (dapl_os_strlen(name_b) != len) { 372 return (DAT_FALSE); 373 } else if (dapl_os_memcmp(name_a, name_b, len)) { 374 return (DAT_FALSE); 375 } else { 376 return (DAT_TRUE); 377 } 378 } 379