Print this page
XXXX introduce drv_sectohz
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/mgt/ibmf/ibmf.c
+++ new/usr/src/uts/common/io/ib/mgt/ibmf/ibmf.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * This file implements the client interfaces of the IBMF.
28 28 */
29 29
30 30 #include <sys/ib/mgt/ibmf/ibmf_impl.h>
31 31
32 32 #define IBMF_SET_CLIENT_SIGNATURE(clientp) { \
33 33 (clientp)->ic_client_sig = (void *)0xf00DdEaD; \
34 34 }
35 35
36 36 #define IBMF_VERIFY_CLIENT_SIGNATURE(clientp) \
37 37 (((clientp) != NULL && (clientp)->ic_client_sig == \
38 38 (void *)0xf00DdEaD) ? B_TRUE: B_FALSE)
39 39
40 40 #define IBMF_INVALID_PKEY(pkey) (((pkey) & 0x7FFF) == 0)
41 41 #define QP1 1
42 42
43 43 extern ibmf_state_t *ibmf_statep;
44 44 extern int ibmf_trace_level;
45 45
46 46 /* ARGSUSED */
47 47 int
48 48 ibmf_register(ibmf_register_info_t *client_infop, uint_t ibmf_version,
49 49 uint_t flags, ibmf_async_event_cb_t client_cb, void *client_cb_args,
50 50 ibmf_handle_t *ibmf_handlep, ibmf_impl_caps_t *ibmf_impl_features)
51 51 {
52 52 ibmf_ci_t *ibmf_cip;
53 53 ibmf_qp_t *ibmf_qpp;
54 54 ibmf_client_t *ibmf_clientp;
55 55 boolean_t error = B_FALSE;
56 56 int status = IBMF_SUCCESS;
57 57 char errmsg[128];
58 58
59 59 IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_start,
60 60 IBMF_TNF_TRACE, "", "ibmf_register() enter, client_infop = %p "
61 61 " ibmf_version = %d, flags = 0x%x, ibmf_impl_featuresp = %p\n",
62 62 tnf_opaque, client_infop, client_infop,
63 63 tnf_uint, ibmf_version, ibmf_version, tnf_uint, flags, flags,
64 64 tnf_opaque, ibmf_impl_features, ibmf_impl_features);
65 65
66 66 /* validate client_infop and ibmf_handlep */
67 67 if ((client_infop == NULL) || (ibmf_handlep == NULL) ||
68 68 (ibmf_impl_features == NULL)) {
69 69 (void) sprintf(errmsg,
70 70 "invalid argument, NULL pointer argument");
71 71 error = B_TRUE;
72 72 status = IBMF_INVALID_ARG;
73 73 goto bail;
74 74 }
75 75
76 76 /* check IBMF version */
77 77 if (ibmf_version != IBMF_VERSION) {
78 78 (void) sprintf(errmsg, "Bad version");
79 79 error = B_TRUE;
80 80 status = IBMF_BAD_VERSION;
81 81 goto bail;
82 82 }
83 83
84 84 /* check flags validity */
85 85 if ((flags & IBMF_REG_FLAG_NO_OFFLOAD) &&
86 86 (flags & IBMF_REG_FLAG_SINGLE_OFFLOAD)) {
87 87 (void) sprintf(errmsg, "Bad flags");
88 88 error = B_TRUE;
89 89 status = IBMF_BAD_FLAGS;
90 90 goto bail;
91 91 }
92 92
93 93 /* check client mask and size */
94 94 status = ibmf_i_validate_class_mask(client_infop);
95 95 if (status != IBMF_SUCCESS) {
96 96 (void) sprintf(errmsg, "invalid class");
97 97 error = B_TRUE;
98 98 goto bail;
99 99 }
100 100 /*
101 101 * verify the node identified by ir_ci_guid exists and that the
102 102 * port ir_port_num is valid.
103 103 */
104 104 status = ibmf_i_validate_ci_guid_and_port(client_infop->ir_ci_guid,
105 105 client_infop->ir_port_num);
106 106 if (status != IBMF_SUCCESS) {
107 107 (void) sprintf(errmsg, "guid/port validation failed");
108 108 error = B_TRUE;
109 109 goto bail;
110 110 }
111 111
112 112 /* get the ci */
113 113 status = ibmf_i_get_ci(client_infop, &ibmf_cip);
114 114 if (status != IBMF_SUCCESS) {
115 115 IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
116 116 ibmf_register_error, IBMF_TNF_ERROR, "",
117 117 "ibmf_register(): %s, guid = 0x%p\n",
118 118 tnf_string, msg, "unable to get ci",
119 119 tnf_ulonglong, guid, client_infop->ir_ci_guid);
120 120 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
121 121 IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
122 122 return (status);
123 123 }
124 124
125 125 /*
126 126 * check if classes and port are already registered for.
127 127 */
128 128 status = ibmf_i_validate_classes_and_port(ibmf_cip, client_infop);
129 129 if (status != IBMF_SUCCESS) {
130 130 mutex_enter(&ibmf_cip->ci_mutex);
131 131 IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
132 132 mutex_exit(&ibmf_cip->ci_mutex);
133 133 /* release ci */
134 134 ibmf_i_release_ci(ibmf_cip);
135 135 (void) sprintf(errmsg,
136 136 "class and port already registered for or unsupported");
137 137 error = B_TRUE;
138 138 goto bail;
139 139 }
140 140
141 141 /*
142 142 * the class is valid, get qp and alloc the client
143 143 */
144 144 /* obtain the qp corresponding to the port and classes */
145 145 status = ibmf_i_get_qp(ibmf_cip, client_infop->ir_port_num,
146 146 client_infop->ir_client_class, &ibmf_qpp);
147 147 if (status != IBMF_SUCCESS) {
148 148 mutex_enter(&ibmf_cip->ci_mutex);
149 149 IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
150 150 mutex_exit(&ibmf_cip->ci_mutex);
151 151 ibmf_i_release_ci(ibmf_cip);
152 152 IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
153 153 ibmf_register_error, IBMF_TNF_ERROR, "",
154 154 "ibmf_register(): %s, class = 0x%x\n",
155 155 tnf_string, msg, "can't get qp",
156 156 tnf_int, class, client_infop->ir_client_class);
157 157 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
158 158 IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
159 159 return (status);
160 160 }
161 161
162 162 /* alloc the client */
163 163 status = ibmf_i_alloc_client(client_infop, flags, &ibmf_clientp);
164 164 if (status != IBMF_SUCCESS) {
165 165 mutex_enter(&ibmf_cip->ci_mutex);
166 166 IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
167 167 mutex_exit(&ibmf_cip->ci_mutex);
168 168 ibmf_i_release_ci(ibmf_cip);
169 169 IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
170 170 ibmf_register_error, IBMF_TNF_ERROR, "",
171 171 "ibmf_register(): %s, class = 0x%x\n",
172 172 tnf_string, msg, "can't alloc client",
173 173 tnf_int, class, client_infop->ir_client_class);
174 174 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
175 175 IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
176 176 return (status);
177 177 }
178 178
179 179 ASSERT(ibmf_clientp != NULL);
180 180
181 181 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_clientp))
182 182
183 183 /* initialize the IBMF client context */
184 184 ibmf_clientp->ic_myci = ibmf_cip;
185 185 ibmf_clientp->ic_qp = ibmf_qpp;
186 186 ibmf_clientp->ic_ci_handle = ibmf_cip->ci_ci_handle;
187 187
188 188 ibmf_clientp->ic_reg_flags = flags;
189 189
190 190 ibmf_clientp->ic_async_cb = client_cb;
191 191 ibmf_clientp->ic_async_cb_arg = client_cb_args;
192 192
193 193 IBMF_SET_CLIENT_SIGNATURE(ibmf_clientp);
194 194
195 195 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibmf_clientp))
196 196
197 197 /* add the client to the list of clients */
198 198 ibmf_i_add_client(ibmf_cip, ibmf_clientp);
199 199
200 200 /* increment kstats for number of registered clients */
201 201 mutex_enter(&ibmf_cip->ci_mutex);
202 202 IBMF_ADD32_PORT_KSTATS(ibmf_cip, clients_registered, 1);
203 203 mutex_exit(&ibmf_cip->ci_mutex);
204 204
205 205 /* Setup ibmf_handlep -- handle is last allocated clientp */
206 206 *ibmf_handlep = (ibmf_handle_t)ibmf_clientp;
207 207 *ibmf_impl_features = 0;
208 208
209 209 bail:
210 210 if (error) {
211 211 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
212 212 ibmf_register_error, IBMF_TNF_ERROR, "",
213 213 "ibmf_register(): %s\n", tnf_string, msg, errmsg);
214 214 }
215 215
216 216 IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
217 217 IBMF_TNF_TRACE, "", "ibmf_register() exit, ibmf_handle = %p\n",
218 218 tnf_opaque, ibmf_handle, *ibmf_handlep);
219 219
220 220 return (status);
221 221 }
222 222
223 223 /* ARGSUSED */
224 224 int
225 225 ibmf_unregister(ibmf_handle_t *ibmf_handlep, uint_t flags)
226 226 {
227 227 ibmf_ci_t *cip;
228 228 ibmf_client_t *clientp;
229 229 boolean_t error = B_FALSE;
230 230 int status = IBMF_SUCCESS;
231 231 char errmsg[128];
232 232 int secs;
233 233
234 234 clientp = (ibmf_client_t *)*ibmf_handlep;
235 235
236 236 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_start,
237 237 IBMF_TNF_TRACE, "", "ibmf_unregister() enter, "
238 238 "ibmf_handlep = %p, flags = 0x%x\n",
239 239 tnf_opaque, ibmf_handle, *ibmf_handlep, tnf_uint, flags, flags);
240 240
241 241 /* check for null ibmf_handlep */
242 242 if (ibmf_handlep == NULL) {
243 243 (void) sprintf(errmsg,
244 244 "invalid argument, NULL pointer argument");
245 245 error = B_TRUE;
246 246 status = IBMF_INVALID_ARG;
247 247 goto bail;
248 248 }
249 249
250 250 /* validate ibmf_handlep */
251 251 if (ibmf_i_is_ibmf_handle_valid(*ibmf_handlep) != IBMF_SUCCESS) {
252 252 (void) sprintf(errmsg, "bad ibmf registration handle");
253 253 error = B_TRUE;
254 254 status = IBMF_BAD_HANDLE;
255 255 goto bail;
256 256 }
257 257
258 258 /* check signature */
259 259 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
260 260 (void) sprintf(errmsg, "bad client signature");
261 261 error = B_TRUE;
262 262 status = IBMF_BAD_HANDLE;
263 263 goto bail;
264 264 }
265 265
↓ open down ↓ |
265 lines elided |
↑ open up ↑ |
266 266 /*
267 267 * Verify the client does not have a receive callback registered.
268 268 * If there are messages, give some time for the messages to be
269 269 * cleaned up.
270 270 */
271 271 secs = 60;
272 272 mutex_enter(&clientp->ic_mutex);
273 273 while (clientp->ic_recv_cb == NULL && clientp->ic_msgs_alloced != 0 &&
274 274 secs > 0) {
275 275 mutex_exit(&clientp->ic_mutex);
276 - delay(drv_usectohz(1000000)); /* one second delay */
276 + delay(drv_sectohz(1)); /* one second delay */
277 277 secs--;
278 278 mutex_enter(&clientp->ic_mutex);
279 279 }
280 280
281 281 if (clientp->ic_recv_cb != NULL || clientp->ic_msgs_alloced != 0) {
282 282 IBMF_TRACE_4(IBMF_TNF_NODEBUG, DPRINT_L1,
283 283 ibmf_unregister_err, IBMF_TNF_ERROR, "",
284 284 "ibmf_unregister(): %s, flags = 0x%x, recv_cb = 0x%p, "
285 285 "msgs_alloced = %d\n",
286 286 tnf_string, msg, "busy with resources", tnf_uint, ic_flags,
287 287 clientp->ic_flags, tnf_opaque, recv_cb, clientp->ic_recv_cb,
288 288 tnf_uint, msgs_allocd, clientp->ic_msgs_alloced);
289 289 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_end,
290 290 IBMF_TNF_TRACE, "", "ibmf_unregister() exit\n");
291 291 mutex_exit(&clientp->ic_mutex);
292 292 return (IBMF_BUSY);
293 293 }
294 294
295 295 mutex_exit(&clientp->ic_mutex);
296 296
297 297 cip = clientp->ic_myci;
298 298
299 299 /* remove the client from the list of clients */
300 300 ibmf_i_delete_client(cip, clientp);
301 301
302 302 /* release the reference to the qp */
303 303 ibmf_i_release_qp(cip, &clientp->ic_qp);
304 304
305 305 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*clientp))
306 306
307 307 /* and free the client structure */
308 308 ibmf_i_free_client(clientp);
309 309
310 310 /* release the ci; this may delete & free the ci structure */
311 311 ibmf_i_release_ci(cip);
312 312
313 313 /* decrement kstats for number of registered clients */
314 314 mutex_enter(&cip->ci_mutex);
315 315 IBMF_SUB32_PORT_KSTATS(cip, clients_registered, 1);
316 316 mutex_exit(&cip->ci_mutex);
317 317
318 318 *ibmf_handlep = NULL;
319 319
320 320 bail:
321 321 if (error) {
322 322 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
323 323 ibmf_unregister_err, IBMF_TNF_ERROR, "",
324 324 "ibmf_unregister(): %s\n", tnf_string, msg, errmsg);
325 325 }
326 326
327 327 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_end,
328 328 IBMF_TNF_TRACE, "", "ibmf_unregister() exit\n");
329 329
330 330 return (status);
331 331 }
332 332
333 333
334 334 /* ARGSUSED */
335 335 int
336 336 ibmf_setup_async_cb(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
337 337 ibmf_msg_cb_t async_msg_cb, void *async_msg_cb_args, uint_t flags)
338 338 {
339 339 ibmf_client_t *clientp;
340 340 boolean_t error = B_FALSE;
341 341 int status = IBMF_SUCCESS;
342 342 char errmsg[128];
343 343
344 344 clientp = (ibmf_client_t *)ibmf_handle;
345 345
346 346 IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_setup_async_cb_start,
347 347 IBMF_TNF_TRACE, "", "ibmf_setup_async_cb() enter, "
348 348 "ibmf_handlep = %p, cb = 0x%p, cb_args = 0x%p, flags = 0x%x\n",
349 349 tnf_opaque, ibmf_handle, ibmf_handle, tnf_opaque, cb,
350 350 async_msg_cb, tnf_opaque, cb_args, async_msg_cb_args,
351 351 tnf_uint, flags, flags);
352 352
353 353 /* check for null ibmf_handlep */
354 354 if (ibmf_handle == NULL) {
355 355 (void) sprintf(errmsg,
356 356 "invalid argument, NULL pointer argument");
357 357 error = B_TRUE;
358 358 status = IBMF_INVALID_ARG;
359 359 goto bail;
360 360 }
361 361
362 362 /* validate ibmf_handle */
363 363 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
364 364 (void) sprintf(errmsg, "bad ibmf registration handle");
365 365 error = B_TRUE;
366 366 status = IBMF_BAD_HANDLE;
367 367 goto bail;
368 368 }
369 369
370 370 /* validate ibmf_qp_handle */
371 371 if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
372 372 IBMF_SUCCESS) {
373 373 (void) sprintf(errmsg, "bad qp handle");
374 374 error = B_TRUE;
375 375 status = IBMF_BAD_QP_HANDLE;
376 376 goto bail;
377 377 }
378 378
379 379 /* check signature */
380 380 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
381 381 (void) sprintf(errmsg, "bad signature");
382 382 error = B_TRUE;
383 383 status = IBMF_BAD_HANDLE;
384 384 goto bail;
385 385 }
386 386
387 387 ASSERT(clientp->ic_myci != NULL);
388 388
389 389 /* store the registered callback in the appropriate context */
390 390 if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
391 391
392 392 /*
393 393 * if using the default QP handle, store the callback in
394 394 * the client context
395 395 */
396 396 mutex_enter(&clientp->ic_mutex);
397 397
398 398 /* check if the callback has already been registered */
399 399 if (clientp->ic_recv_cb != NULL) {
400 400 mutex_exit(&clientp->ic_mutex);
401 401 (void) sprintf(errmsg, "cb already exists");
402 402 error = B_TRUE;
403 403 status = IBMF_CB_REGISTERED;
404 404 goto bail;
405 405 }
406 406
407 407 clientp->ic_recv_cb = async_msg_cb;
408 408 clientp->ic_recv_cb_arg = async_msg_cb_args;
409 409 mutex_exit(&clientp->ic_mutex);
410 410
411 411 } else {
412 412 ibmf_alt_qp_t *qp_ctxp = (ibmf_alt_qp_t *)ibmf_qp_handle;
413 413
414 414 /*
415 415 * if using an alternate QP handle, store the callback in
416 416 * the alternate QP context because there can be more than
417 417 * one alternate QP associated with a client
418 418 */
419 419 mutex_enter(&qp_ctxp->isq_mutex);
420 420
421 421 /* check if the callback has already been registered */
422 422 if (qp_ctxp->isq_recv_cb != NULL) {
423 423 mutex_exit(&qp_ctxp->isq_mutex);
424 424 (void) sprintf(errmsg, "cb already exists");
425 425 error = B_TRUE;
426 426 status = IBMF_CB_REGISTERED;
427 427 goto bail;
428 428 }
429 429
430 430 qp_ctxp->isq_recv_cb = async_msg_cb;
431 431 qp_ctxp->isq_recv_cb_arg = async_msg_cb_args;
432 432
433 433 mutex_exit(&qp_ctxp->isq_mutex);
434 434 }
435 435
436 436 bail:
437 437 if (error) {
438 438 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
439 439 ibmf_setup_async_cb_err, IBMF_TNF_ERROR, "",
440 440 "ibmf_setup_async_cb(): %s\n", tnf_string, msg, errmsg);
441 441 }
442 442
443 443 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_setup_async_cb_end,
444 444 IBMF_TNF_TRACE, "", "ibmf_setup_async_cb() exit\n");
445 445
446 446 return (status);
447 447 }
448 448
449 449
450 450 /* ARGSUSED */
451 451 int
452 452 ibmf_tear_down_async_cb(ibmf_handle_t ibmf_handle,
453 453 ibmf_qp_handle_t ibmf_qp_handle, uint_t flags)
454 454 {
455 455 ibmf_client_t *clientp;
456 456 boolean_t error = B_FALSE;
457 457 int status = IBMF_SUCCESS;
458 458 char errmsg[128];
459 459
460 460 clientp = (ibmf_client_t *)ibmf_handle;
461 461
462 462 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_tear_down_async_cb_start,
463 463 IBMF_TNF_TRACE, "", "ibmf_tear_down_async_cb() enter, "
464 464 "ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x\n",
465 465 tnf_opaque, ibmf_handle, ibmf_handle,
466 466 tnf_opaque, ibmf_qp_handle, ibmf_qp_handle, tnf_uint, flags, flags);
467 467
468 468 /* check for null ibmf_handlep */
469 469 if (ibmf_handle == NULL) {
470 470 (void) sprintf(errmsg,
471 471 "invalid argument, NULL pointer argument");
472 472 error = B_TRUE;
473 473 status = IBMF_INVALID_ARG;
474 474 goto bail;
475 475 }
476 476
477 477 /* validate ibmf_handle */
478 478 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
479 479 (void) sprintf(errmsg, "bad ibmf registration handle");
480 480 error = B_TRUE;
481 481 status = IBMF_BAD_HANDLE;
482 482 goto bail;
483 483 }
484 484
485 485 /* validate ibmf_qp_handle */
486 486 if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
487 487 IBMF_SUCCESS) {
488 488 (void) sprintf(errmsg, "bad qp handle");
489 489 error = B_TRUE;
490 490 status = IBMF_BAD_QP_HANDLE;
491 491 goto bail;
492 492 }
493 493
494 494 /* check signature */
495 495 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
496 496 (void) sprintf(errmsg, "bad signature");
497 497 error = B_TRUE;
498 498 status = IBMF_BAD_HANDLE;
499 499 goto bail;
500 500 }
501 501
502 502 ASSERT(clientp->ic_myci != NULL);
503 503
504 504 /* remove the registered callback from the appropriate context */
505 505 if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
506 506
507 507 mutex_enter(&clientp->ic_mutex);
508 508
509 509 /* check if callback has not been registered */
510 510 if (clientp->ic_recv_cb == NULL) {
511 511 mutex_exit(&clientp->ic_mutex);
512 512 (void) sprintf(errmsg, "no cb exists");
513 513 error = B_TRUE;
514 514 status = IBMF_CB_NOT_REGISTERED;
515 515 goto bail;
516 516 }
517 517
518 518 /*
519 519 * if an unsolicited MAD just arrived for this
520 520 * client, wait for it to be processed
521 521 */
522 522 while (clientp->ic_flags & IBMF_CLIENT_RECV_CB_ACTIVE) {
523 523 clientp->ic_flags |= IBMF_CLIENT_TEAR_DOWN_CB;
524 524 cv_wait(&clientp->ic_recv_cb_teardown_cv,
525 525 &clientp->ic_mutex);
526 526 clientp->ic_flags &= ~IBMF_CLIENT_TEAR_DOWN_CB;
527 527 }
528 528
529 529 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clientp->ic_recv_cb,
530 530 clientp->ic_recv_cb_arg))
531 531
532 532 /*
533 533 * if using the default QP handle, remove the callback from
534 534 * the client context
535 535 */
536 536 clientp->ic_recv_cb = NULL;
537 537 clientp->ic_recv_cb_arg = NULL;
538 538
539 539 ASSERT((clientp->ic_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0);
540 540
541 541 mutex_exit(&clientp->ic_mutex);
542 542 } else {
543 543 ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
544 544
545 545 mutex_enter(&qpp->isq_mutex);
546 546
547 547 /* check if callback has not been registered */
548 548 if (qpp->isq_recv_cb == NULL) {
549 549 mutex_exit(&qpp->isq_mutex);
550 550 (void) sprintf(errmsg, "no cb exists");
551 551 error = B_TRUE;
552 552 status = IBMF_CB_NOT_REGISTERED;
553 553 goto bail;
554 554 }
555 555
556 556 /*
557 557 * if an unsolicited MAD just arrived for this
558 558 * client on the alternate QP, wait for it to be processed
559 559 */
560 560 while (qpp->isq_flags & IBMF_CLIENT_RECV_CB_ACTIVE) {
561 561 qpp->isq_flags |= IBMF_CLIENT_TEAR_DOWN_CB;
562 562 cv_wait(&qpp->isq_recv_cb_teardown_cv,
563 563 &qpp->isq_mutex);
564 564 qpp->isq_flags &= ~IBMF_CLIENT_TEAR_DOWN_CB;
565 565 }
566 566
567 567 /*
568 568 * if using an alternate QP handle, remove the callback from
569 569 * the alternate QP context
570 570 */
571 571 qpp->isq_recv_cb = NULL;
572 572 qpp->isq_recv_cb_arg = NULL;
573 573
574 574 ASSERT((qpp->isq_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0);
575 575
576 576 mutex_exit(&qpp->isq_mutex);
577 577 }
578 578
579 579 bail:
580 580 if (error) {
581 581 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
582 582 ibmf_tear_down_async_cb_err, IBMF_TNF_ERROR, "",
583 583 "ibmf_tear_down_async_cb(): %s\n", tnf_string, msg, errmsg);
584 584 }
585 585
586 586 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_tear_down_async_cb_end,
587 587 IBMF_TNF_TRACE, "", "ibmf_tear_down_async_cb() exit\n");
588 588
589 589 return (status);
590 590 }
591 591
592 592
593 593 int
594 594 ibmf_alloc_msg(ibmf_handle_t ibmf_handle, int flag, ibmf_msg_t **ibmf_msgpp)
595 595 {
596 596 ibmf_msg_impl_t *ibmf_msg_impl;
597 597 ibmf_client_t *clientp;
598 598 int km_flags;
599 599 boolean_t error = B_FALSE;
600 600 int status = IBMF_SUCCESS;
601 601 char errmsg[128];
602 602
603 603 clientp = (ibmf_client_t *)ibmf_handle;
604 604
605 605 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_msg_start,
606 606 IBMF_TNF_TRACE, "", "ibmf_alloc_msg() enter, "
607 607 "ibmf_handle = %p, flags = 0x%x\n",
608 608 tnf_opaque, ibmf_handle, ibmf_handle, tnf_uint, flag, flag);
609 609
610 610 /* check for null ibmf_handle and ibmf_msgpp */
611 611 if ((ibmf_handle == NULL) || (ibmf_msgpp == NULL)) {
612 612 (void) sprintf(errmsg,
613 613 "invalid argument, NULL pointer argument");
614 614 error = B_TRUE;
615 615 status = IBMF_INVALID_ARG;
616 616 goto bail;
617 617 }
618 618
619 619 /* validate ibmf_handle */
620 620 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
621 621 (void) sprintf(errmsg, "bad ibmf registration handle");
622 622 error = B_TRUE;
623 623 status = IBMF_BAD_HANDLE;
624 624 goto bail;
625 625 }
626 626
627 627 /* check signature */
628 628 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
629 629 (void) sprintf(errmsg, "bad signature");
630 630 error = B_TRUE;
631 631 status = IBMF_BAD_HANDLE;
632 632 goto bail;
633 633 }
634 634
635 635 /* validate flag */
636 636 if (flag != IBMF_ALLOC_SLEEP && flag != IBMF_ALLOC_NOSLEEP) {
637 637 (void) sprintf(errmsg, "invalid flags, flags = 0x%x", flag);
638 638 error = B_TRUE;
639 639 status = IBMF_BAD_FLAGS;
640 640 goto bail;
641 641 }
642 642
643 643 /* set flags for kmem allocaton */
644 644 km_flags = (flag == IBMF_ALLOC_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
645 645
646 646 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl))
647 647
648 648 /* call the internal function to allocate the IBMF message context */
649 649 status = ibmf_i_alloc_msg(clientp, &ibmf_msg_impl, km_flags);
650 650 if (status != IBMF_SUCCESS) {
651 651 mutex_enter(&clientp->ic_kstat_mutex);
652 652 IBMF_ADD32_KSTATS(clientp, msg_allocs_failed, 1);
653 653 mutex_exit(&clientp->ic_kstat_mutex);
654 654 (void) sprintf(errmsg, "message allocation failure");
655 655 error = B_TRUE;
656 656 goto bail;
657 657 }
658 658
659 659 /* increment counter and kstats for number of allocated messages */
660 660 mutex_enter(&clientp->ic_mutex);
661 661 clientp->ic_msgs_alloced++;
662 662 mutex_exit(&clientp->ic_mutex);
663 663 mutex_enter(&clientp->ic_kstat_mutex);
664 664 IBMF_ADD32_KSTATS(clientp, msgs_alloced, 1);
665 665 mutex_exit(&clientp->ic_kstat_mutex);
666 666
667 667 /* initialize the msg */
668 668 ibmf_msg_impl->im_client = clientp;
669 669 cv_init(&ibmf_msg_impl->im_trans_cv, NULL, CV_DRIVER, NULL);
670 670 mutex_init(&ibmf_msg_impl->im_mutex, NULL, MUTEX_DRIVER, NULL);
671 671 *ibmf_msgpp = (ibmf_msg_t *)ibmf_msg_impl;
672 672
673 673 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl))
674 674
675 675 bail:
676 676 if (error) {
677 677 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
678 678 ibmf_alloc_msg_err, IBMF_TNF_ERROR, "",
679 679 "ibmf_alloc_msg(): %s\n", tnf_string, msg, errmsg);
680 680 }
681 681
682 682 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_msg_end,
683 683 IBMF_TNF_TRACE, "", "ibmf_alloc_msg() exit\n");
684 684
685 685 return (status);
686 686 }
687 687
688 688
689 689 int
690 690 ibmf_free_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp)
691 691 {
692 692 ibmf_client_t *clientp;
693 693 ibmf_msg_impl_t *ibmf_msg_impl;
694 694 boolean_t error = B_FALSE;
695 695 int status = IBMF_SUCCESS;
696 696 char errmsg[128];
697 697 timeout_id_t msg_rp_set_id, msg_tr_set_id;
698 698 timeout_id_t msg_rp_unset_id, msg_tr_unset_id;
699 699
700 700 IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_msg_start,
701 701 IBMF_TNF_TRACE, "", "ibmf_free_msg() enter, " "ibmf_handle = %p\n",
702 702 tnf_opaque, ibmf_handle, ibmf_handle);
703 703
704 704 /* check for null ibmf_handle and ibmf_msgpp */
705 705 if ((ibmf_handle == NULL) || (ibmf_msgpp == NULL)) {
706 706 (void) sprintf(errmsg,
707 707 "invalid argument, NULL pointer argument");
708 708 error = B_TRUE;
709 709 status = IBMF_INVALID_ARG;
710 710 goto bail;
711 711 }
712 712
713 713 /* validate ibmf_handle */
714 714 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
715 715 (void) sprintf(errmsg, "bad ibmf registration handle");
716 716 error = B_TRUE;
717 717 status = IBMF_BAD_HANDLE;
718 718 goto bail;
719 719 }
720 720
721 721 ibmf_msg_impl = (ibmf_msg_impl_t *)*ibmf_msgpp;
722 722
723 723 /* check for null message pointer */
724 724 if (ibmf_msg_impl == NULL) {
725 725 (void) sprintf(errmsg, "null message");
726 726 error = B_TRUE;
727 727 status = IBMF_FAILURE;
728 728 goto bail;
729 729 }
730 730
731 731 mutex_enter(&ibmf_msg_impl->im_mutex);
732 732
733 733 /* check if message context flags indicate a busy message */
734 734 if (ibmf_msg_impl->im_flags & IBMF_MSG_FLAGS_BUSY) {
735 735 mutex_exit(&ibmf_msg_impl->im_mutex);
736 736 (void) sprintf(errmsg, "message in use");
737 737 error = B_TRUE;
738 738 status = IBMF_BUSY;
739 739 goto bail;
740 740 }
741 741
742 742 ASSERT((ibmf_msg_impl->im_flags & IBMF_MSG_FLAGS_ON_LIST) == 0);
743 743
744 744 /* Initialize the timer ID holders */
745 745 msg_rp_set_id = msg_tr_set_id = 0;
746 746 msg_rp_unset_id = msg_tr_unset_id = 0;
747 747
748 748 /* Clear any timers that are still set */
749 749
750 750 if (ibmf_msg_impl->im_rp_timeout_id != 0) {
751 751 msg_rp_set_id = ibmf_msg_impl->im_rp_timeout_id;
752 752 ibmf_msg_impl->im_rp_timeout_id = 0;
753 753 }
754 754
755 755 if (ibmf_msg_impl->im_tr_timeout_id != 0) {
756 756 msg_tr_set_id = ibmf_msg_impl->im_tr_timeout_id;
757 757 ibmf_msg_impl->im_tr_timeout_id = 0;
758 758 }
759 759
760 760 if (ibmf_msg_impl->im_rp_unset_timeout_id != 0) {
761 761 msg_rp_unset_id = ibmf_msg_impl->im_rp_unset_timeout_id;
762 762 ibmf_msg_impl->im_rp_unset_timeout_id = 0;
763 763 }
764 764
765 765 if (ibmf_msg_impl->im_tr_unset_timeout_id != 0) {
766 766 msg_tr_unset_id = ibmf_msg_impl->im_tr_unset_timeout_id;
767 767 ibmf_msg_impl->im_tr_unset_timeout_id = 0;
768 768 }
769 769
770 770 /* mark the message context flags to indicate a freed message */
771 771 ibmf_msg_impl->im_flags |= IBMF_MSG_FLAGS_FREE;
772 772
773 773 mutex_exit(&ibmf_msg_impl->im_mutex);
774 774
775 775 /* cast pointer to client context */
776 776 clientp = (ibmf_client_t *)ibmf_handle;
777 777
778 778 /* check signature */
779 779 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
780 780 (void) sprintf(errmsg, "bad signature");
781 781 error = B_TRUE;
782 782 status = IBMF_BAD_HANDLE;
783 783 goto bail;
784 784 }
785 785
786 786 /* Clear the timers */
787 787 if (msg_rp_unset_id != 0) {
788 788 (void) untimeout(msg_rp_unset_id);
789 789 }
790 790
791 791 if (msg_tr_unset_id != 0) {
792 792 (void) untimeout(msg_tr_unset_id);
793 793 }
794 794
795 795 if (msg_rp_set_id != 0) {
796 796 (void) untimeout(msg_rp_set_id);
797 797 }
798 798
799 799 if (msg_tr_set_id != 0) {
800 800 (void) untimeout(msg_tr_set_id);
801 801 }
802 802
803 803 /* destroy the condition variables */
804 804 cv_destroy(&ibmf_msg_impl->im_trans_cv);
805 805
806 806 /* decrement counter and kstats for number of allocated messages */
807 807 mutex_enter(&clientp->ic_mutex);
808 808 clientp->ic_msgs_alloced--;
809 809 mutex_exit(&clientp->ic_mutex);
810 810 mutex_enter(&clientp->ic_kstat_mutex);
811 811 IBMF_SUB32_KSTATS(clientp, msgs_alloced, 1);
812 812 mutex_exit(&clientp->ic_kstat_mutex);
813 813
814 814 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl,
815 815 ibmf_msg_impl->im_msgbufs_recv,
816 816 ibmf_msg_impl->im_msgbufs_send))
817 817
818 818 /* call the internal function to free the message context */
819 819 ibmf_i_free_msg(ibmf_msg_impl);
820 820
821 821 *ibmf_msgpp = NULL;
822 822
823 823 bail:
824 824 if (error) {
825 825 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
826 826 ibmf_free_msg_err, IBMF_TNF_ERROR, "",
827 827 "ibmf_free_msg(): %s\n", tnf_string, msg, errmsg);
828 828 }
829 829
830 830 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_msg_end,
831 831 IBMF_TNF_TRACE, "", "ibmf_free_msg() exit\n");
832 832
833 833 return (status);
834 834 }
835 835
836 836
837 837 /* ARGSUSED */
838 838 int
839 839 ibmf_msg_transport(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
840 840 ibmf_msg_t *msgp, ibmf_retrans_t *retrans, ibmf_msg_cb_t msg_cb,
841 841 void *msg_cb_args, uint_t flags)
842 842 {
843 843 ibmf_client_t *clientp;
844 844 ibmf_msg_impl_t *msgimplp;
845 845 boolean_t blocking, loopback, error = B_FALSE;
846 846 int status = IBMF_SUCCESS;
847 847 sm_dr_mad_hdr_t *dr_hdr;
848 848 char errmsg[128];
849 849
850 850 IBMF_TRACE_5(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_msg_transport_start,
851 851 IBMF_TNF_TRACE, "", "ibmf_msg_transport() enter, "
852 852 "ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x "
853 853 "msgp = 0x%p, retrans = 0x%p\n",
854 854 tnf_opaque, ibmf_handle, ibmf_handle,
855 855 tnf_opaque, ibmf_qp_handle, ibmf_qp_handle, tnf_uint, flags, flags,
856 856 tnf_opaque, msgp, msgp, tnf_opaque, retrans, retrans);
857 857
858 858 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*msgp,*msgimplp))
859 859
860 860 /* check for null ibmf_handle and msgp */
861 861 if ((ibmf_handle == NULL) || (msgp == NULL)) {
862 862 (void) sprintf(errmsg,
863 863 "invalid argument, NULL pointer argument");
864 864 error = B_TRUE;
865 865 status = IBMF_INVALID_ARG;
866 866 goto bail;
867 867 }
868 868
869 869 /* validate ibmf_handle */
870 870 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
871 871 (void) sprintf(errmsg, "bad ibmf registration handle");
872 872 error = B_TRUE;
873 873 status = IBMF_BAD_HANDLE;
874 874 goto bail;
875 875 }
876 876
877 877 /* validate ibmf_qp_handle */
878 878 if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
879 879 IBMF_SUCCESS) {
880 880 (void) sprintf(errmsg, "bad qp handle");
881 881 error = B_TRUE;
882 882 status = IBMF_BAD_QP_HANDLE;
883 883 goto bail;
884 884 }
885 885
886 886 clientp = (ibmf_client_t *)ibmf_handle;
887 887
888 888 /* check signature */
889 889 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
890 890 (void) sprintf(errmsg, "bad signature");
891 891 error = B_TRUE;
892 892 status = IBMF_BAD_HANDLE;
893 893 goto bail;
894 894 }
895 895
896 896 /*
897 897 * Check the validity of the pkey and qkey in the posted packet
898 898 * For special QPs do the check for QP1 only
899 899 * For the alternate qps, the pkey and qkey should match the
900 900 * pkey and qkey maintained in the ibmf cached qp context
901 901 */
902 902 if ((ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) &&
903 903 ((clientp->ic_client_info.client_class != SUBN_AGENT) &&
904 904 (clientp->ic_client_info.client_class != SUBN_ADM_AGENT) &&
905 905 (clientp->ic_client_info.client_class != SUBN_MANAGER))) {
906 906
907 907 if ((msgp->im_local_addr.ia_p_key != IBMF_P_KEY_DEF_FULL) &&
908 908 (msgp->im_local_addr.ia_p_key != IBMF_P_KEY_DEF_LIMITED)) {
909 909 (void) sprintf(errmsg,
910 910 "PKey in packet not default PKey");
911 911 error = B_TRUE;
912 912 status = IBMF_BAD_QP_HANDLE;
913 913 goto bail;
914 914 }
915 915
916 916 if (msgp->im_local_addr.ia_q_key != IBMF_MGMT_Q_KEY) {
917 917 (void) sprintf(errmsg, "QKey in packet not Mgt QKey");
918 918 error = B_TRUE;
919 919 status = IBMF_BAD_QP_HANDLE;
920 920 goto bail;
921 921 }
922 922 } else if (ibmf_qp_handle != IBMF_QP_HANDLE_DEFAULT) {
923 923 ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
924 924
925 925 /* alternate QP context */
926 926
927 927 mutex_enter(&qpp->isq_mutex);
928 928
929 929 if (msgp->im_local_addr.ia_p_key != qpp->isq_pkey) {
930 930 mutex_exit(&qpp->isq_mutex);
931 931 (void) sprintf(errmsg, "PKey in packet does not match "
932 932 "PKey in the QP context");
933 933 error = B_TRUE;
934 934 status = IBMF_BAD_QP_HANDLE;
935 935 goto bail;
936 936 }
937 937
938 938 if (msgp->im_local_addr.ia_q_key != qpp->isq_qkey) {
939 939 mutex_exit(&qpp->isq_mutex);
940 940 (void) sprintf(errmsg, "QKey in packet does not match "
941 941 "QKey in the QP context");
942 942 error = B_TRUE;
943 943 status = IBMF_BAD_QP_HANDLE;
944 944 goto bail;
945 945 }
946 946
947 947 mutex_exit(&qpp->isq_mutex);
948 948 }
949 949
950 950 msgimplp = (ibmf_msg_impl_t *)msgp;
951 951
952 952 ASSERT(msgimplp->im_client != NULL);
953 953 ASSERT(msgimplp->im_client == clientp);
954 954
955 955 msgimplp->im_transp_op_flags = flags;
956 956
957 957 mutex_enter(&msgimplp->im_mutex);
958 958
959 959 if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
960 960 if (msgimplp->im_msgbufs_send.im_bufs_mad_hdr == NULL) {
961 961 mutex_exit(&msgimplp->im_mutex);
962 962 (void) sprintf(errmsg, "Send buffer MAD header data "
963 963 "not provided for special QP");
964 964 error = B_TRUE;
965 965 status = IBMF_BAD_SIZE;
966 966 goto bail;
967 967 }
968 968 } else {
969 969 ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
970 970
971 971 mutex_enter(&qpp->isq_mutex);
972 972
973 973 if (((qpp->isq_flags & IBMF_RAW_ONLY) == 0) &&
974 974 (msgimplp->im_msgbufs_send.im_bufs_mad_hdr == NULL)) {
975 975 mutex_exit(&qpp->isq_mutex);
976 976 mutex_exit(&msgimplp->im_mutex);
977 977 (void) sprintf(errmsg, "Send buffer MAD header data "
978 978 "not provided for alternate QP");
979 979 error = B_TRUE;
980 980 status = IBMF_BAD_SIZE;
981 981 goto bail;
982 982 }
983 983 mutex_exit(&qpp->isq_mutex);
984 984 }
985 985
986 986 /* check if client has freed the message by calling ibmf_free_msg() */
987 987 if (msgimplp->im_flags & IBMF_MSG_FLAGS_FREE) {
988 988 mutex_exit(&msgimplp->im_mutex);
989 989 (void) sprintf(errmsg, "Message is being freed");
990 990 error = B_TRUE;
991 991 status = IBMF_BUSY;
992 992 goto bail;
993 993 }
994 994
995 995 /*
996 996 * check if the message is already in use in an
997 997 * ibmf_msg_transport() call
998 998 */
999 999 if (msgimplp->im_flags & IBMF_MSG_FLAGS_BUSY) {
1000 1000 mutex_exit(&msgimplp->im_mutex);
1001 1001 (void) sprintf(errmsg,
1002 1002 "Message is being processed by an other thread");
1003 1003 error = B_TRUE;
1004 1004 status = IBMF_BUSY;
1005 1005 goto bail;
1006 1006 }
1007 1007
1008 1008 msgimplp->im_flags = IBMF_MSG_FLAGS_BUSY;
1009 1009
1010 1010 mutex_exit(&msgimplp->im_mutex);
1011 1011
1012 1012 /* check for the Directed Route SMP loopback case */
1013 1013 loopback = B_FALSE;
1014 1014 dr_hdr = (sm_dr_mad_hdr_t *)msgimplp->im_msgbufs_send.im_bufs_mad_hdr;
1015 1015 if ((dr_hdr->MgmtClass == MAD_MGMT_CLASS_SUBN_DIRECT_ROUTE) &&
1016 1016 (dr_hdr->HopCount == 0)) {
1017 1017 loopback = B_TRUE;
1018 1018 }
1019 1019
1020 1020 /* check for and perform DR loopback on tavor */
1021 1021 status = ibmf_i_check_for_loopback(msgimplp, msg_cb, msg_cb_args,
1022 1022 retrans, &loopback);
1023 1023 if (status != IBMF_SUCCESS) {
1024 1024 (void) sprintf(errmsg, "dr_loopback_check failed");
1025 1025 error = B_TRUE;
1026 1026 mutex_enter(&msgimplp->im_mutex);
1027 1027 msgimplp->im_flags &= ~IBMF_MSG_FLAGS_BUSY;
1028 1028 mutex_exit(&msgimplp->im_mutex);
1029 1029 goto bail;
1030 1030 }
1031 1031 if (loopback == B_TRUE) {
1032 1032 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1033 1033 ibmf_msg_transport_end, IBMF_TNF_TRACE, "",
1034 1034 "ibmf_msg_transport() exit, dr_loopback ok\n");
1035 1035 return (IBMF_SUCCESS);
1036 1036 }
1037 1037
1038 1038 if (msg_cb == NULL) {
1039 1039 blocking = B_TRUE;
1040 1040 } else {
1041 1041 blocking = B_FALSE;
1042 1042 }
1043 1043
1044 1044 /* initialize the message context */
1045 1045 ibmf_i_init_msg(msgimplp, msg_cb, msg_cb_args, retrans, blocking);
1046 1046
1047 1047 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*msgp,*msgimplp))
1048 1048
1049 1049 /* call the internal function to transport the message */
1050 1050 status = ibmf_i_msg_transport(clientp, ibmf_qp_handle, msgimplp,
1051 1051 blocking);
1052 1052 if (status != IBMF_SUCCESS) {
1053 1053 (void) sprintf(errmsg, "message transport failed");
1054 1054 error = B_TRUE;
1055 1055 mutex_enter(&msgimplp->im_mutex);
1056 1056 msgimplp->im_flags &= ~IBMF_MSG_FLAGS_BUSY;
1057 1057 mutex_exit(&msgimplp->im_mutex);
1058 1058 goto bail;
1059 1059 }
1060 1060
1061 1061 bail:
1062 1062 if (error) {
1063 1063 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
1064 1064 ibmf_msg_transport_err, IBMF_TNF_ERROR, "",
1065 1065 "ibmf_msg_transport(): %s\n", tnf_string, msg, errmsg);
1066 1066 }
1067 1067
1068 1068 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_msg_transport_end,
1069 1069 IBMF_TNF_TRACE, "", "ibmf_msg_transport() exit\n");
1070 1070
1071 1071 return (status);
1072 1072 }
1073 1073
1074 1074
1075 1075 /* ARGSUSED */
1076 1076 int
1077 1077 ibmf_alloc_qp(ibmf_handle_t ibmf_handle, ib_pkey_t p_key, ib_qkey_t q_key,
1078 1078 uint_t flags, ibmf_qp_handle_t *ibmf_qp_handlep)
1079 1079 {
1080 1080 ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
1081 1081 uint_t alloc_flags;
1082 1082 ibmf_alt_qp_t *qp_ctx;
1083 1083 boolean_t error = B_FALSE;
1084 1084 int status = IBMF_SUCCESS;
1085 1085 char errmsg[128];
1086 1086
1087 1087 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_qp_start,
1088 1088 IBMF_TNF_TRACE, "", "ibmf_alloc_qp() enter, "
1089 1089 "ibmf_handlep = %p, p_key = 0x%x, q_key = 0x%x\n",
1090 1090 tnf_opaque, ibmf_handle, ibmf_handle,
1091 1091 tnf_uint, pkey, p_key, tnf_uint, qkey, q_key);
1092 1092
1093 1093 /* check for null ibmf_handle and ibmf_qp_handle */
1094 1094 if ((ibmf_handle == NULL) || (ibmf_qp_handlep == NULL)) {
1095 1095 (void) sprintf(errmsg,
1096 1096 "invalid argument, NULL pointer argument");
1097 1097 error = B_TRUE;
1098 1098 status = IBMF_INVALID_ARG;
1099 1099 goto bail;
1100 1100 }
1101 1101
1102 1102 /* validate ibmf_handle */
1103 1103 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
1104 1104 (void) sprintf(errmsg, "bad ibmf registration handle");
1105 1105 error = B_TRUE;
1106 1106 status = IBMF_BAD_HANDLE;
1107 1107 goto bail;
1108 1108 }
1109 1109
1110 1110 /* check signature */
1111 1111 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
1112 1112 (void) sprintf(errmsg, "bad signature");
1113 1113 error = B_TRUE;
1114 1114 status = IBMF_BAD_HANDLE;
1115 1115 goto bail;
1116 1116 }
1117 1117
1118 1118 /* validate PKey */
1119 1119 if (IBMF_INVALID_PKEY(p_key)) {
1120 1120 (void) sprintf(errmsg, "invalid value in p_key argument");
1121 1121 error = B_TRUE;
1122 1122 status = IBMF_INVALID_ARG;
1123 1123 goto bail;
1124 1124 }
1125 1125
1126 1126 if (((flags & IBMF_ALT_QP_MAD_NO_RMPP) == 0) &&
1127 1127 ((flags & IBMF_ALT_QP_MAD_RMPP) == 0) &&
1128 1128 ((flags & IBMF_ALT_QP_RAW_ONLY) == 0)) {
1129 1129 (void) sprintf(errmsg, "invalid flags combination");
1130 1130 error = B_TRUE;
1131 1131 status = IBMF_BAD_FLAGS;
1132 1132 goto bail;
1133 1133 }
1134 1134
1135 1135 alloc_flags = IBMF_ALLOC_SLEEP;
1136 1136
1137 1137 /* call the internal function to allocate the alternate QP context */
1138 1138 status = ibmf_i_alloc_qp(clientp, p_key, q_key, alloc_flags,
1139 1139 ibmf_qp_handlep);
1140 1140 if (status != IBMF_SUCCESS) {
1141 1141 mutex_enter(&clientp->ic_kstat_mutex);
1142 1142 IBMF_ADD32_KSTATS(clientp, alt_qp_allocs_failed, 1);
1143 1143 mutex_exit(&clientp->ic_kstat_mutex);
1144 1144 (void) sprintf(errmsg, "unable to allocate QP");
1145 1145 error = B_TRUE;
1146 1146 status = IBMF_NO_RESOURCES;
1147 1147 goto bail;
1148 1148 }
1149 1149
1150 1150 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp_ctx))
1151 1151
1152 1152 qp_ctx = (ibmf_alt_qp_t *)*ibmf_qp_handlep;
1153 1153
1154 1154 /* initialize the alternate qp context */
1155 1155 if (flags & IBMF_ALT_QP_MAD_NO_RMPP)
1156 1156 qp_ctx->isq_flags |= IBMF_MAD_ONLY;
1157 1157
1158 1158 if (flags & IBMF_ALT_QP_RAW_ONLY)
1159 1159 qp_ctx->isq_flags |= IBMF_RAW_ONLY;
1160 1160
1161 1161 if (flags & IBMF_ALT_QP_MAD_RMPP)
1162 1162 qp_ctx->isq_supports_rmpp = B_TRUE;
1163 1163 else
1164 1164 qp_ctx->isq_supports_rmpp = B_FALSE;
1165 1165
1166 1166 bail:
1167 1167 if (error) {
1168 1168 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
1169 1169 ibmf_alloc_qp_err, IBMF_TNF_ERROR, "",
1170 1170 "ibmf_alloc_qp(): %s\n", tnf_string, msg, errmsg);
1171 1171 }
1172 1172
1173 1173 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_qp_end,
1174 1174 IBMF_TNF_TRACE, "", "ibmf_alloc_qp() exit\n");
1175 1175
1176 1176
1177 1177 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*qp_ctx))
1178 1178
1179 1179 return (status);
1180 1180 }
1181 1181
1182 1182
1183 1183 /* ARGSUSED */
1184 1184 int
1185 1185 ibmf_query_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
1186 1186 uint_t *qp_num, ib_pkey_t *p_key, ib_qkey_t *q_key, uint8_t *portnum,
1187 1187 uint_t flags)
1188 1188 {
1189 1189 ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
1190 1190 ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)ibmf_qp_handle;
1191 1191 uint_t query_flags;
1192 1192 boolean_t error = B_FALSE;
1193 1193 int status = IBMF_SUCCESS;
1194 1194 char errmsg[128];
1195 1195
1196 1196 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_query_qp_start,
1197 1197 IBMF_TNF_TRACE, "", "ibmf_query_qp() enter, "
1198 1198 "ibmf_handlep = %p, ibmf_qp_handle = %p\n",
1199 1199 tnf_opaque, ibmf_handle, ibmf_handle,
1200 1200 tnf_opaque, ibmf_qp_handle, ibmf_qp_handle);
1201 1201
1202 1202 /* check for null args */
1203 1203 if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL) ||
1204 1204 (qp_num == NULL) || (p_key == NULL) || (q_key == NULL) ||
1205 1205 (portnum == NULL)) {
1206 1206 (void) sprintf(errmsg,
1207 1207 "invalid argument, NULL pointer argument");
1208 1208 error = B_TRUE;
1209 1209 status = IBMF_INVALID_ARG;
1210 1210 goto bail;
1211 1211 }
1212 1212
1213 1213 /* validate ibmf_handle */
1214 1214 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
1215 1215 (void) sprintf(errmsg, "bad ibmf registration handle");
1216 1216 error = B_TRUE;
1217 1217 status = IBMF_BAD_HANDLE;
1218 1218 goto bail;
1219 1219 }
1220 1220
1221 1221 /* validate ibmf_qp_handle */
1222 1222 if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
1223 1223 IBMF_SUCCESS) {
1224 1224 (void) sprintf(errmsg, "bad qp handle");
1225 1225 error = B_TRUE;
1226 1226 status = IBMF_BAD_QP_HANDLE;
1227 1227 goto bail;
1228 1228 }
1229 1229
1230 1230 /* validate ibmf_qp_handle */
1231 1231 if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
1232 1232 (void) sprintf(errmsg, "bad qp handle (default)");
1233 1233 error = B_TRUE;
1234 1234 status = IBMF_BAD_QP_HANDLE;
1235 1235 goto bail;
1236 1236 }
1237 1237
1238 1238 /* check signature */
1239 1239 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
1240 1240 (void) sprintf(errmsg, "bad client signature");
1241 1241 error = B_TRUE;
1242 1242 status = IBMF_BAD_HANDLE;
1243 1243 goto bail;
1244 1244 }
1245 1245
1246 1246 /* validate client context handle */
1247 1247 if (qp_ctx->isq_client_hdl != clientp) {
1248 1248 (void) sprintf(errmsg, "bad QP handle");
1249 1249 error = B_TRUE;
1250 1250 status = IBMF_BAD_QP_HANDLE;
1251 1251 goto bail;
1252 1252 }
1253 1253
1254 1254 query_flags = IBMF_ALLOC_NOSLEEP;
1255 1255
1256 1256 /* call the internal function to query the alternate qp */
1257 1257 status = ibmf_i_query_qp(ibmf_qp_handle, query_flags, qp_num, p_key,
1258 1258 q_key, portnum);
1259 1259 if (status != IBMF_SUCCESS) {
1260 1260 (void) sprintf(errmsg, "unable to query QP");
1261 1261 error = B_TRUE;
1262 1262 goto bail;
1263 1263 }
1264 1264
1265 1265 bail:
1266 1266 if (error) {
1267 1267 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
1268 1268 ibmf_query_qp_err, IBMF_TNF_ERROR, "",
1269 1269 "ibmf_query_qp(): %s\n", tnf_string, msg, errmsg);
1270 1270 }
1271 1271
1272 1272 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_query_qp_end,
1273 1273 IBMF_TNF_TRACE, "", "ibmf_query_qp() exit, qp = %d, "
1274 1274 "pkey = 0x%x, qkey = 0x%x\n", tnf_uint, qp_num, *qp_num,
1275 1275 tnf_uint, pkey, *p_key, tnf_uint, qkey, *q_key);
1276 1276
1277 1277 return (status);
1278 1278 }
1279 1279
1280 1280
1281 1281 /* ARGSUSED */
1282 1282 int
1283 1283 ibmf_modify_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
1284 1284 ib_pkey_t p_key, ib_qkey_t q_key, uint_t flags)
1285 1285 {
1286 1286 ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
1287 1287 ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)ibmf_qp_handle;
1288 1288 uint_t modify_flags;
1289 1289 boolean_t error = B_FALSE;
1290 1290 int status = IBMF_SUCCESS;
1291 1291 char errmsg[128];
1292 1292
1293 1293 IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_modify_qp_start,
1294 1294 IBMF_TNF_TRACE, "", "ibmf_modify_qp() enter, "
1295 1295 "ibmf_handlep = %p, ibmf_qp_handle = %p, pkey = 0x%x, "
1296 1296 "qkey = 0x%x\n", tnf_opaque, ibmf_handle, ibmf_handle,
1297 1297 tnf_opaque, ibmf_qp_handle, ibmf_qp_handle,
1298 1298 tnf_uint, p_key, p_key, tnf_uint, q_key, q_key);
1299 1299
1300 1300 /* check for null args */
1301 1301 if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL)) {
1302 1302 (void) sprintf(errmsg,
1303 1303 "invalid argument, NULL pointer argument");
1304 1304 error = B_TRUE;
1305 1305 status = IBMF_INVALID_ARG;
1306 1306 goto bail;
1307 1307 }
1308 1308
1309 1309 /* validate ibmf_handle */
1310 1310 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
1311 1311 (void) sprintf(errmsg, "bad ibmf registration handle");
1312 1312 error = B_TRUE;
1313 1313 status = IBMF_BAD_HANDLE;
1314 1314 goto bail;
1315 1315 }
1316 1316
1317 1317 /* validate ibmf_qp_handle */
1318 1318 if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
1319 1319 IBMF_SUCCESS) {
1320 1320 (void) sprintf(errmsg, "bad qp handle");
1321 1321 error = B_TRUE;
1322 1322 status = IBMF_BAD_QP_HANDLE;
1323 1323 goto bail;
1324 1324 }
1325 1325
1326 1326 /* validate ibmf_qp_handle */
1327 1327 if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
1328 1328 (void) sprintf(errmsg, "bad qp handle (default)");
1329 1329 error = B_TRUE;
1330 1330 status = IBMF_BAD_QP_HANDLE;
1331 1331 goto bail;
1332 1332 }
1333 1333
1334 1334 /* check signature */
1335 1335 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
1336 1336 (void) sprintf(errmsg, "bad client signature");
1337 1337 error = B_TRUE;
1338 1338 status = IBMF_BAD_HANDLE;
1339 1339 goto bail;
1340 1340 }
1341 1341
1342 1342 /* validate PKey */
1343 1343 if (IBMF_INVALID_PKEY(p_key)) {
1344 1344 (void) sprintf(errmsg, "invalid value in p_key argument");
1345 1345 error = B_TRUE;
1346 1346 status = IBMF_INVALID_ARG;
1347 1347 goto bail;
1348 1348 }
1349 1349
1350 1350 if (qp_ctx->isq_client_hdl != clientp) {
1351 1351 (void) sprintf(errmsg, "bad QP handle");
1352 1352 error = B_TRUE;
1353 1353 status = IBMF_BAD_QP_HANDLE;
1354 1354 goto bail;
1355 1355 }
1356 1356
1357 1357 modify_flags = IBMF_ALLOC_SLEEP;
1358 1358
1359 1359 /* call the internal function to modify the qp */
1360 1360 status = ibmf_i_modify_qp(ibmf_qp_handle, p_key, q_key, modify_flags);
1361 1361 if (status != IBMF_SUCCESS) {
1362 1362 (void) sprintf(errmsg, "unable to modify QP");
1363 1363 error = B_TRUE;
1364 1364 goto bail;
1365 1365 }
1366 1366
1367 1367 bail:
1368 1368 if (error) {
1369 1369 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
1370 1370 ibmf_modify_qp_err, IBMF_TNF_ERROR, "",
1371 1371 "ibmf_modify_qp(): %s\n", tnf_string, msg, errmsg);
1372 1372 }
1373 1373
1374 1374 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_modify_qp_end,
1375 1375 IBMF_TNF_TRACE, "", "ibmf_modify_qp() exit\n");
1376 1376
1377 1377 return (status);
1378 1378 }
1379 1379
1380 1380 /* ARGSUSED */
1381 1381 int
1382 1382 ibmf_free_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t *ibmf_qp_handle,
1383 1383 uint_t flags)
1384 1384 {
1385 1385 ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
1386 1386 ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)*ibmf_qp_handle;
1387 1387 uint_t modify_flags;
1388 1388 boolean_t error = B_FALSE;
1389 1389 int status = IBMF_SUCCESS;
1390 1390 char errmsg[128];
1391 1391
1392 1392 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_qp_start,
1393 1393 IBMF_TNF_TRACE, "", "ibmf_free_qp() enter, "
1394 1394 "ibmf_handlep = %p, ibmf_qp_handle = %p\n",
1395 1395 tnf_opaque, ibmf_handle, ibmf_handle,
1396 1396 tnf_opaque, ibmf_qp_handle, *ibmf_qp_handle);
1397 1397
1398 1398 /* check for null args */
1399 1399 if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL)) {
1400 1400 (void) sprintf(errmsg,
1401 1401 "invalid argument, NULL pointer argument");
1402 1402 error = B_TRUE;
1403 1403 status = IBMF_INVALID_ARG;
1404 1404 goto bail;
1405 1405 }
1406 1406
1407 1407 /* validate ibmf_handle */
1408 1408 if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
1409 1409 (void) sprintf(errmsg, "bad ibmf registration handle");
1410 1410 error = B_TRUE;
1411 1411 status = IBMF_BAD_HANDLE;
1412 1412 goto bail;
1413 1413 }
1414 1414
1415 1415 /* validate ibmf_qp_handle */
1416 1416 if (ibmf_i_is_qp_handle_valid(ibmf_handle, *ibmf_qp_handle) !=
1417 1417 IBMF_SUCCESS) {
1418 1418 (void) sprintf(errmsg, "bad qp handle");
1419 1419 error = B_TRUE;
1420 1420 status = IBMF_BAD_QP_HANDLE;
1421 1421 goto bail;
1422 1422 }
1423 1423
1424 1424 /* validate ibmf_qp_handle */
1425 1425 if (*ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
1426 1426 (void) sprintf(errmsg, "bad qp handle (default)");
1427 1427 error = B_TRUE;
1428 1428 status = IBMF_BAD_QP_HANDLE;
1429 1429 goto bail;
1430 1430 }
1431 1431
1432 1432 /* check signature */
1433 1433 if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
1434 1434 (void) sprintf(errmsg, "bad client signature");
1435 1435 error = B_TRUE;
1436 1436 status = IBMF_BAD_HANDLE;
1437 1437 goto bail;
1438 1438 }
1439 1439
1440 1440 /* validate client context handle */
1441 1441 if (qp_ctx->isq_client_hdl != clientp) {
1442 1442 (void) sprintf(errmsg, "bad QP handle");
1443 1443 error = B_TRUE;
1444 1444 status = IBMF_BAD_QP_HANDLE;
1445 1445 goto bail;
1446 1446 }
1447 1447
1448 1448 mutex_enter(&qp_ctx->isq_mutex);
1449 1449
1450 1450 if (qp_ctx->isq_recv_cb != NULL) {
1451 1451 mutex_exit(&qp_ctx->isq_mutex);
1452 1452 (void) sprintf(errmsg, "QP busy, callback active");
1453 1453 error = B_TRUE;
1454 1454 status = IBMF_BUSY;
1455 1455 goto bail;
1456 1456 }
1457 1457
1458 1458 mutex_exit(&qp_ctx->isq_mutex);
1459 1459
1460 1460 modify_flags = IBMF_ALLOC_SLEEP;
1461 1461
1462 1462 status = ibmf_i_free_qp(*ibmf_qp_handle, modify_flags);
1463 1463 if (status != IBMF_SUCCESS) {
1464 1464 (void) sprintf(errmsg, "unable to free QP");
1465 1465 error = B_TRUE;
1466 1466 goto bail;
1467 1467 }
1468 1468
1469 1469 *ibmf_qp_handle = NULL;
1470 1470
1471 1471 bail:
1472 1472 if (error) {
1473 1473 IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
1474 1474 ibmf_free_qp_err, IBMF_TNF_ERROR, "",
1475 1475 "ibmf_free_qp(): %s\n", tnf_string, msg, errmsg);
1476 1476 }
1477 1477
1478 1478 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_qp_end,
1479 1479 IBMF_TNF_TRACE, "", "ibmf_free_qp() exit\n");
1480 1480
1481 1481 return (status);
1482 1482 }
↓ open down ↓ |
1196 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX