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
dapl_provider_list_create(void)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
dapl_provider_list_destroy(void)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
dapl_provider_list_size(void)234 dapl_provider_list_size(void)
235 {
236 return (g_dapl_provider_list.size);
237 }
238
239
240 DAT_RETURN
dapl_provider_list_insert(IN const char * name,IN DAT_PROVIDER ** p_data)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
dapl_provider_list_search(IN const char * name,OUT DAT_PROVIDER ** p_data)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
dapl_provider_list_remove(IN const char * name)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
dapl_provider_list_key_cmp(const char * name_a,const char * name_b)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