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 *
dapls_sp_alloc(IN DAPL_IA * ia_ptr,IN DAT_BOOLEAN is_psp)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
dapls_sp_free_sp(IN DAPL_SP * sp_ptr)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
dapl_sp_link_cr(IN DAPL_SP * sp_ptr,IN DAPL_CR * cr_ptr)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 *
dapl_sp_search_cr(IN DAPL_SP * sp_ptr,IN ib_cm_handle_t ib_cm_handle)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
dapl_sp_remove_cr(IN DAPL_SP * sp_ptr,IN DAPL_CR * cr_ptr)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