dapl_provider.c revision 9517:b4839b0aa7a4
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
50DAPL_PROVIDER_LIST 		g_dapl_provider_list;
51
52
53/*
54 * the function table for this provider
55 */
56
57DAT_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
153static DAT_BOOLEAN
154dapl_provider_list_key_cmp(
155    const char *name_a,
156    const char *name_b);
157
158
159/*
160 *
161 * Function Definitions
162 *
163 */
164
165DAT_RETURN
166dapl_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
200bail:
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
217DAT_RETURN
218dapl_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
233DAT_COUNT
234dapl_provider_list_size(void)
235{
236	return (g_dapl_provider_list.size);
237}
238
239
240DAT_RETURN
241dapl_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
288bail:
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
300DAT_RETURN
301dapl_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
323bail:
324	return (status);
325}
326
327
328DAT_RETURN
329dapl_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
357bail:
358	return (status);
359}
360
361
362DAT_BOOLEAN
363dapl_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