10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
58082SRamaswamy.Tummala@Sun.COM * Common Development and Distribution License (the "License").
68082SRamaswamy.Tummala@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*12787SLida.Horn@Oracle.COM
220Sstevel@tonic-gate /*
23*12787SLida.Horn@Oracle.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * This file implements the client interfaces of the IBMF.
280Sstevel@tonic-gate */
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_impl.h>
310Sstevel@tonic-gate
320Sstevel@tonic-gate #define IBMF_SET_CLIENT_SIGNATURE(clientp) { \
330Sstevel@tonic-gate (clientp)->ic_client_sig = (void *)0xf00DdEaD; \
340Sstevel@tonic-gate }
350Sstevel@tonic-gate
360Sstevel@tonic-gate #define IBMF_VERIFY_CLIENT_SIGNATURE(clientp) \
370Sstevel@tonic-gate (((clientp) != NULL && (clientp)->ic_client_sig == \
380Sstevel@tonic-gate (void *)0xf00DdEaD) ? B_TRUE: B_FALSE)
390Sstevel@tonic-gate
400Sstevel@tonic-gate #define IBMF_INVALID_PKEY(pkey) (((pkey) & 0x7FFF) == 0)
410Sstevel@tonic-gate #define QP1 1
420Sstevel@tonic-gate
430Sstevel@tonic-gate extern ibmf_state_t *ibmf_statep;
440Sstevel@tonic-gate extern int ibmf_trace_level;
450Sstevel@tonic-gate
460Sstevel@tonic-gate /* ARGSUSED */
470Sstevel@tonic-gate int
ibmf_register(ibmf_register_info_t * client_infop,uint_t ibmf_version,uint_t flags,ibmf_async_event_cb_t client_cb,void * client_cb_args,ibmf_handle_t * ibmf_handlep,ibmf_impl_caps_t * ibmf_impl_features)480Sstevel@tonic-gate ibmf_register(ibmf_register_info_t *client_infop, uint_t ibmf_version,
490Sstevel@tonic-gate uint_t flags, ibmf_async_event_cb_t client_cb, void *client_cb_args,
500Sstevel@tonic-gate ibmf_handle_t *ibmf_handlep, ibmf_impl_caps_t *ibmf_impl_features)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate ibmf_ci_t *ibmf_cip;
530Sstevel@tonic-gate ibmf_qp_t *ibmf_qpp;
540Sstevel@tonic-gate ibmf_client_t *ibmf_clientp;
550Sstevel@tonic-gate boolean_t error = B_FALSE;
560Sstevel@tonic-gate int status = IBMF_SUCCESS;
570Sstevel@tonic-gate char errmsg[128];
580Sstevel@tonic-gate
590Sstevel@tonic-gate IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_start,
600Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_register() enter, client_infop = %p "
610Sstevel@tonic-gate " ibmf_version = %d, flags = 0x%x, ibmf_impl_featuresp = %p\n",
620Sstevel@tonic-gate tnf_opaque, client_infop, client_infop,
630Sstevel@tonic-gate tnf_uint, ibmf_version, ibmf_version, tnf_uint, flags, flags,
640Sstevel@tonic-gate tnf_opaque, ibmf_impl_features, ibmf_impl_features);
650Sstevel@tonic-gate
660Sstevel@tonic-gate /* validate client_infop and ibmf_handlep */
670Sstevel@tonic-gate if ((client_infop == NULL) || (ibmf_handlep == NULL) ||
680Sstevel@tonic-gate (ibmf_impl_features == NULL)) {
690Sstevel@tonic-gate (void) sprintf(errmsg,
700Sstevel@tonic-gate "invalid argument, NULL pointer argument");
710Sstevel@tonic-gate error = B_TRUE;
720Sstevel@tonic-gate status = IBMF_INVALID_ARG;
730Sstevel@tonic-gate goto bail;
740Sstevel@tonic-gate }
750Sstevel@tonic-gate
760Sstevel@tonic-gate /* check IBMF version */
770Sstevel@tonic-gate if (ibmf_version != IBMF_VERSION) {
780Sstevel@tonic-gate (void) sprintf(errmsg, "Bad version");
790Sstevel@tonic-gate error = B_TRUE;
800Sstevel@tonic-gate status = IBMF_BAD_VERSION;
810Sstevel@tonic-gate goto bail;
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
840Sstevel@tonic-gate /* check flags validity */
850Sstevel@tonic-gate if ((flags & IBMF_REG_FLAG_NO_OFFLOAD) &&
860Sstevel@tonic-gate (flags & IBMF_REG_FLAG_SINGLE_OFFLOAD)) {
870Sstevel@tonic-gate (void) sprintf(errmsg, "Bad flags");
880Sstevel@tonic-gate error = B_TRUE;
890Sstevel@tonic-gate status = IBMF_BAD_FLAGS;
900Sstevel@tonic-gate goto bail;
910Sstevel@tonic-gate }
920Sstevel@tonic-gate
930Sstevel@tonic-gate /* check client mask and size */
940Sstevel@tonic-gate status = ibmf_i_validate_class_mask(client_infop);
950Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
960Sstevel@tonic-gate (void) sprintf(errmsg, "invalid class");
970Sstevel@tonic-gate error = B_TRUE;
980Sstevel@tonic-gate goto bail;
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate /*
1010Sstevel@tonic-gate * verify the node identified by ir_ci_guid exists and that the
1020Sstevel@tonic-gate * port ir_port_num is valid.
1030Sstevel@tonic-gate */
1040Sstevel@tonic-gate status = ibmf_i_validate_ci_guid_and_port(client_infop->ir_ci_guid,
1050Sstevel@tonic-gate client_infop->ir_port_num);
1060Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
1070Sstevel@tonic-gate (void) sprintf(errmsg, "guid/port validation failed");
1080Sstevel@tonic-gate error = B_TRUE;
1090Sstevel@tonic-gate goto bail;
1100Sstevel@tonic-gate }
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate /* get the ci */
1130Sstevel@tonic-gate status = ibmf_i_get_ci(client_infop, &ibmf_cip);
1140Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
1150Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
1160Sstevel@tonic-gate ibmf_register_error, IBMF_TNF_ERROR, "",
1170Sstevel@tonic-gate "ibmf_register(): %s, guid = 0x%p\n",
1180Sstevel@tonic-gate tnf_string, msg, "unable to get ci",
1190Sstevel@tonic-gate tnf_ulonglong, guid, client_infop->ir_ci_guid);
1200Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
1210Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
1220Sstevel@tonic-gate return (status);
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate /*
1260Sstevel@tonic-gate * check if classes and port are already registered for.
1270Sstevel@tonic-gate */
1280Sstevel@tonic-gate status = ibmf_i_validate_classes_and_port(ibmf_cip, client_infop);
1290Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
1300Sstevel@tonic-gate mutex_enter(&ibmf_cip->ci_mutex);
1310Sstevel@tonic-gate IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
1320Sstevel@tonic-gate mutex_exit(&ibmf_cip->ci_mutex);
1330Sstevel@tonic-gate /* release ci */
1340Sstevel@tonic-gate ibmf_i_release_ci(ibmf_cip);
1350Sstevel@tonic-gate (void) sprintf(errmsg,
1360Sstevel@tonic-gate "class and port already registered for or unsupported");
1370Sstevel@tonic-gate error = B_TRUE;
1380Sstevel@tonic-gate goto bail;
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate * the class is valid, get qp and alloc the client
1430Sstevel@tonic-gate */
1440Sstevel@tonic-gate /* obtain the qp corresponding to the port and classes */
1450Sstevel@tonic-gate status = ibmf_i_get_qp(ibmf_cip, client_infop->ir_port_num,
1460Sstevel@tonic-gate client_infop->ir_client_class, &ibmf_qpp);
1470Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
1480Sstevel@tonic-gate mutex_enter(&ibmf_cip->ci_mutex);
1490Sstevel@tonic-gate IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
1500Sstevel@tonic-gate mutex_exit(&ibmf_cip->ci_mutex);
1510Sstevel@tonic-gate ibmf_i_release_ci(ibmf_cip);
1520Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
1530Sstevel@tonic-gate ibmf_register_error, IBMF_TNF_ERROR, "",
1540Sstevel@tonic-gate "ibmf_register(): %s, class = 0x%x\n",
1550Sstevel@tonic-gate tnf_string, msg, "can't get qp",
1560Sstevel@tonic-gate tnf_int, class, client_infop->ir_client_class);
1570Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
1580Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
1590Sstevel@tonic-gate return (status);
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate /* alloc the client */
1630Sstevel@tonic-gate status = ibmf_i_alloc_client(client_infop, flags, &ibmf_clientp);
1640Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
1650Sstevel@tonic-gate mutex_enter(&ibmf_cip->ci_mutex);
1660Sstevel@tonic-gate IBMF_ADD32_PORT_KSTATS(ibmf_cip, client_regs_failed, 1);
1670Sstevel@tonic-gate mutex_exit(&ibmf_cip->ci_mutex);
1680Sstevel@tonic-gate ibmf_i_release_ci(ibmf_cip);
1690Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
1700Sstevel@tonic-gate ibmf_register_error, IBMF_TNF_ERROR, "",
1710Sstevel@tonic-gate "ibmf_register(): %s, class = 0x%x\n",
1720Sstevel@tonic-gate tnf_string, msg, "can't alloc client",
1730Sstevel@tonic-gate tnf_int, class, client_infop->ir_client_class);
1740Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
1750Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_register() exit\n");
1760Sstevel@tonic-gate return (status);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate ASSERT(ibmf_clientp != NULL);
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_clientp))
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate /* initialize the IBMF client context */
1840Sstevel@tonic-gate ibmf_clientp->ic_myci = ibmf_cip;
1850Sstevel@tonic-gate ibmf_clientp->ic_qp = ibmf_qpp;
1860Sstevel@tonic-gate ibmf_clientp->ic_ci_handle = ibmf_cip->ci_ci_handle;
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate ibmf_clientp->ic_reg_flags = flags;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate ibmf_clientp->ic_async_cb = client_cb;
1910Sstevel@tonic-gate ibmf_clientp->ic_async_cb_arg = client_cb_args;
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate IBMF_SET_CLIENT_SIGNATURE(ibmf_clientp);
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibmf_clientp))
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate /* add the client to the list of clients */
1980Sstevel@tonic-gate ibmf_i_add_client(ibmf_cip, ibmf_clientp);
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate /* increment kstats for number of registered clients */
2010Sstevel@tonic-gate mutex_enter(&ibmf_cip->ci_mutex);
2020Sstevel@tonic-gate IBMF_ADD32_PORT_KSTATS(ibmf_cip, clients_registered, 1);
2030Sstevel@tonic-gate mutex_exit(&ibmf_cip->ci_mutex);
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate /* Setup ibmf_handlep -- handle is last allocated clientp */
2060Sstevel@tonic-gate *ibmf_handlep = (ibmf_handle_t)ibmf_clientp;
2070Sstevel@tonic-gate *ibmf_impl_features = 0;
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate bail:
2100Sstevel@tonic-gate if (error) {
2110Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
2120Sstevel@tonic-gate ibmf_register_error, IBMF_TNF_ERROR, "",
2130Sstevel@tonic-gate "ibmf_register(): %s\n", tnf_string, msg, errmsg);
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate
2160Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_register_end,
2170Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_register() exit, ibmf_handle = %p\n",
2180Sstevel@tonic-gate tnf_opaque, ibmf_handle, *ibmf_handlep);
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate return (status);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /* ARGSUSED */
2240Sstevel@tonic-gate int
ibmf_unregister(ibmf_handle_t * ibmf_handlep,uint_t flags)2250Sstevel@tonic-gate ibmf_unregister(ibmf_handle_t *ibmf_handlep, uint_t flags)
2260Sstevel@tonic-gate {
2270Sstevel@tonic-gate ibmf_ci_t *cip;
2280Sstevel@tonic-gate ibmf_client_t *clientp;
2290Sstevel@tonic-gate boolean_t error = B_FALSE;
2300Sstevel@tonic-gate int status = IBMF_SUCCESS;
2310Sstevel@tonic-gate char errmsg[128];
2328082SRamaswamy.Tummala@Sun.COM int secs;
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate clientp = (ibmf_client_t *)*ibmf_handlep;
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_start,
2370Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_unregister() enter, "
2380Sstevel@tonic-gate "ibmf_handlep = %p, flags = 0x%x\n",
2390Sstevel@tonic-gate tnf_opaque, ibmf_handle, *ibmf_handlep, tnf_uint, flags, flags);
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate /* check for null ibmf_handlep */
2420Sstevel@tonic-gate if (ibmf_handlep == NULL) {
2430Sstevel@tonic-gate (void) sprintf(errmsg,
2440Sstevel@tonic-gate "invalid argument, NULL pointer argument");
2450Sstevel@tonic-gate error = B_TRUE;
2460Sstevel@tonic-gate status = IBMF_INVALID_ARG;
2470Sstevel@tonic-gate goto bail;
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate /* validate ibmf_handlep */
2510Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(*ibmf_handlep) != IBMF_SUCCESS) {
2520Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
2530Sstevel@tonic-gate error = B_TRUE;
2540Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
2550Sstevel@tonic-gate goto bail;
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate /* check signature */
2590Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
2600Sstevel@tonic-gate (void) sprintf(errmsg, "bad client signature");
2610Sstevel@tonic-gate error = B_TRUE;
2620Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
2630Sstevel@tonic-gate goto bail;
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate /*
2678082SRamaswamy.Tummala@Sun.COM * Verify the client does not have a receive callback registered.
2688082SRamaswamy.Tummala@Sun.COM * If there are messages, give some time for the messages to be
2698082SRamaswamy.Tummala@Sun.COM * cleaned up.
2700Sstevel@tonic-gate */
2718082SRamaswamy.Tummala@Sun.COM secs = 60;
2720Sstevel@tonic-gate mutex_enter(&clientp->ic_mutex);
2738082SRamaswamy.Tummala@Sun.COM while (clientp->ic_recv_cb == NULL && clientp->ic_msgs_alloced != 0 &&
2748082SRamaswamy.Tummala@Sun.COM secs > 0) {
2758082SRamaswamy.Tummala@Sun.COM mutex_exit(&clientp->ic_mutex);
2768082SRamaswamy.Tummala@Sun.COM delay(drv_usectohz(1000000)); /* one second delay */
2778082SRamaswamy.Tummala@Sun.COM secs--;
2788082SRamaswamy.Tummala@Sun.COM mutex_enter(&clientp->ic_mutex);
2798082SRamaswamy.Tummala@Sun.COM }
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate if (clientp->ic_recv_cb != NULL || clientp->ic_msgs_alloced != 0) {
2820Sstevel@tonic-gate IBMF_TRACE_4(IBMF_TNF_NODEBUG, DPRINT_L1,
2830Sstevel@tonic-gate ibmf_unregister_err, IBMF_TNF_ERROR, "",
2840Sstevel@tonic-gate "ibmf_unregister(): %s, flags = 0x%x, recv_cb = 0x%p, "
2850Sstevel@tonic-gate "msgs_alloced = %d\n",
2860Sstevel@tonic-gate tnf_string, msg, "busy with resources", tnf_uint, ic_flags,
2870Sstevel@tonic-gate clientp->ic_flags, tnf_opaque, recv_cb, clientp->ic_recv_cb,
2880Sstevel@tonic-gate tnf_uint, msgs_allocd, clientp->ic_msgs_alloced);
2890Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_end,
2900Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_unregister() exit\n");
2910Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
2920Sstevel@tonic-gate return (IBMF_BUSY);
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate cip = clientp->ic_myci;
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate /* remove the client from the list of clients */
3000Sstevel@tonic-gate ibmf_i_delete_client(cip, clientp);
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate /* release the reference to the qp */
3030Sstevel@tonic-gate ibmf_i_release_qp(cip, &clientp->ic_qp);
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*clientp))
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate /* and free the client structure */
3080Sstevel@tonic-gate ibmf_i_free_client(clientp);
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate /* release the ci; this may delete & free the ci structure */
3110Sstevel@tonic-gate ibmf_i_release_ci(cip);
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate /* decrement kstats for number of registered clients */
3140Sstevel@tonic-gate mutex_enter(&cip->ci_mutex);
3150Sstevel@tonic-gate IBMF_SUB32_PORT_KSTATS(cip, clients_registered, 1);
3160Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate *ibmf_handlep = NULL;
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate bail:
3210Sstevel@tonic-gate if (error) {
3220Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
3230Sstevel@tonic-gate ibmf_unregister_err, IBMF_TNF_ERROR, "",
3240Sstevel@tonic-gate "ibmf_unregister(): %s\n", tnf_string, msg, errmsg);
3250Sstevel@tonic-gate }
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_unregister_end,
3280Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_unregister() exit\n");
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate return (status);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate /* ARGSUSED */
3350Sstevel@tonic-gate int
ibmf_setup_async_cb(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t ibmf_qp_handle,ibmf_msg_cb_t async_msg_cb,void * async_msg_cb_args,uint_t flags)3360Sstevel@tonic-gate ibmf_setup_async_cb(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
3370Sstevel@tonic-gate ibmf_msg_cb_t async_msg_cb, void *async_msg_cb_args, uint_t flags)
3380Sstevel@tonic-gate {
3390Sstevel@tonic-gate ibmf_client_t *clientp;
3400Sstevel@tonic-gate boolean_t error = B_FALSE;
3410Sstevel@tonic-gate int status = IBMF_SUCCESS;
3420Sstevel@tonic-gate char errmsg[128];
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate clientp = (ibmf_client_t *)ibmf_handle;
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_setup_async_cb_start,
3470Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_setup_async_cb() enter, "
3480Sstevel@tonic-gate "ibmf_handlep = %p, cb = 0x%p, cb_args = 0x%p, flags = 0x%x\n",
3490Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle, tnf_opaque, cb,
3500Sstevel@tonic-gate async_msg_cb, tnf_opaque, cb_args, async_msg_cb_args,
3510Sstevel@tonic-gate tnf_uint, flags, flags);
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate /* check for null ibmf_handlep */
3540Sstevel@tonic-gate if (ibmf_handle == NULL) {
3550Sstevel@tonic-gate (void) sprintf(errmsg,
3560Sstevel@tonic-gate "invalid argument, NULL pointer argument");
3570Sstevel@tonic-gate error = B_TRUE;
3580Sstevel@tonic-gate status = IBMF_INVALID_ARG;
3590Sstevel@tonic-gate goto bail;
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate /* validate ibmf_handle */
3630Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
3640Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
3650Sstevel@tonic-gate error = B_TRUE;
3660Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
3670Sstevel@tonic-gate goto bail;
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /* validate ibmf_qp_handle */
3710Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
3720Sstevel@tonic-gate IBMF_SUCCESS) {
3730Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
3740Sstevel@tonic-gate error = B_TRUE;
3750Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
3760Sstevel@tonic-gate goto bail;
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate /* check signature */
3800Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
3810Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
3820Sstevel@tonic-gate error = B_TRUE;
3830Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
3840Sstevel@tonic-gate goto bail;
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate ASSERT(clientp->ic_myci != NULL);
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate /* store the registered callback in the appropriate context */
3900Sstevel@tonic-gate if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate /*
3930Sstevel@tonic-gate * if using the default QP handle, store the callback in
3940Sstevel@tonic-gate * the client context
3950Sstevel@tonic-gate */
3960Sstevel@tonic-gate mutex_enter(&clientp->ic_mutex);
3970Sstevel@tonic-gate
3980Sstevel@tonic-gate /* check if the callback has already been registered */
3990Sstevel@tonic-gate if (clientp->ic_recv_cb != NULL) {
4000Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
4010Sstevel@tonic-gate (void) sprintf(errmsg, "cb already exists");
4020Sstevel@tonic-gate error = B_TRUE;
4030Sstevel@tonic-gate status = IBMF_CB_REGISTERED;
4040Sstevel@tonic-gate goto bail;
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate clientp->ic_recv_cb = async_msg_cb;
4080Sstevel@tonic-gate clientp->ic_recv_cb_arg = async_msg_cb_args;
4090Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate } else {
4120Sstevel@tonic-gate ibmf_alt_qp_t *qp_ctxp = (ibmf_alt_qp_t *)ibmf_qp_handle;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate /*
4150Sstevel@tonic-gate * if using an alternate QP handle, store the callback in
4160Sstevel@tonic-gate * the alternate QP context because there can be more than
4170Sstevel@tonic-gate * one alternate QP associated with a client
4180Sstevel@tonic-gate */
4190Sstevel@tonic-gate mutex_enter(&qp_ctxp->isq_mutex);
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate /* check if the callback has already been registered */
4220Sstevel@tonic-gate if (qp_ctxp->isq_recv_cb != NULL) {
4230Sstevel@tonic-gate mutex_exit(&qp_ctxp->isq_mutex);
4240Sstevel@tonic-gate (void) sprintf(errmsg, "cb already exists");
4250Sstevel@tonic-gate error = B_TRUE;
4260Sstevel@tonic-gate status = IBMF_CB_REGISTERED;
4270Sstevel@tonic-gate goto bail;
4280Sstevel@tonic-gate }
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate qp_ctxp->isq_recv_cb = async_msg_cb;
4310Sstevel@tonic-gate qp_ctxp->isq_recv_cb_arg = async_msg_cb_args;
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate mutex_exit(&qp_ctxp->isq_mutex);
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate bail:
4370Sstevel@tonic-gate if (error) {
4380Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
4390Sstevel@tonic-gate ibmf_setup_async_cb_err, IBMF_TNF_ERROR, "",
4400Sstevel@tonic-gate "ibmf_setup_async_cb(): %s\n", tnf_string, msg, errmsg);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_setup_async_cb_end,
4440Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_setup_async_cb() exit\n");
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate return (status);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate /* ARGSUSED */
4510Sstevel@tonic-gate int
ibmf_tear_down_async_cb(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t ibmf_qp_handle,uint_t flags)4520Sstevel@tonic-gate ibmf_tear_down_async_cb(ibmf_handle_t ibmf_handle,
4530Sstevel@tonic-gate ibmf_qp_handle_t ibmf_qp_handle, uint_t flags)
4540Sstevel@tonic-gate {
4550Sstevel@tonic-gate ibmf_client_t *clientp;
4560Sstevel@tonic-gate boolean_t error = B_FALSE;
4570Sstevel@tonic-gate int status = IBMF_SUCCESS;
4580Sstevel@tonic-gate char errmsg[128];
4590Sstevel@tonic-gate
4600Sstevel@tonic-gate clientp = (ibmf_client_t *)ibmf_handle;
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_tear_down_async_cb_start,
4630Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_tear_down_async_cb() enter, "
4640Sstevel@tonic-gate "ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x\n",
4650Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle,
4660Sstevel@tonic-gate tnf_opaque, ibmf_qp_handle, ibmf_qp_handle, tnf_uint, flags, flags);
4670Sstevel@tonic-gate
4680Sstevel@tonic-gate /* check for null ibmf_handlep */
4690Sstevel@tonic-gate if (ibmf_handle == NULL) {
4700Sstevel@tonic-gate (void) sprintf(errmsg,
4710Sstevel@tonic-gate "invalid argument, NULL pointer argument");
4720Sstevel@tonic-gate error = B_TRUE;
4730Sstevel@tonic-gate status = IBMF_INVALID_ARG;
4740Sstevel@tonic-gate goto bail;
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate /* validate ibmf_handle */
4780Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
4790Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
4800Sstevel@tonic-gate error = B_TRUE;
4810Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
4820Sstevel@tonic-gate goto bail;
4830Sstevel@tonic-gate }
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate /* validate ibmf_qp_handle */
4860Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
4870Sstevel@tonic-gate IBMF_SUCCESS) {
4880Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
4890Sstevel@tonic-gate error = B_TRUE;
4900Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
4910Sstevel@tonic-gate goto bail;
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate /* check signature */
4950Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
4960Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
4970Sstevel@tonic-gate error = B_TRUE;
4980Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
4990Sstevel@tonic-gate goto bail;
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate ASSERT(clientp->ic_myci != NULL);
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate /* remove the registered callback from the appropriate context */
5050Sstevel@tonic-gate if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate mutex_enter(&clientp->ic_mutex);
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate /* check if callback has not been registered */
5100Sstevel@tonic-gate if (clientp->ic_recv_cb == NULL) {
5110Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
5120Sstevel@tonic-gate (void) sprintf(errmsg, "no cb exists");
5130Sstevel@tonic-gate error = B_TRUE;
5140Sstevel@tonic-gate status = IBMF_CB_NOT_REGISTERED;
5150Sstevel@tonic-gate goto bail;
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate /*
5190Sstevel@tonic-gate * if an unsolicited MAD just arrived for this
5200Sstevel@tonic-gate * client, wait for it to be processed
5210Sstevel@tonic-gate */
5220Sstevel@tonic-gate while (clientp->ic_flags & IBMF_CLIENT_RECV_CB_ACTIVE) {
5230Sstevel@tonic-gate clientp->ic_flags |= IBMF_CLIENT_TEAR_DOWN_CB;
5240Sstevel@tonic-gate cv_wait(&clientp->ic_recv_cb_teardown_cv,
5250Sstevel@tonic-gate &clientp->ic_mutex);
5260Sstevel@tonic-gate clientp->ic_flags &= ~IBMF_CLIENT_TEAR_DOWN_CB;
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clientp->ic_recv_cb,
5300Sstevel@tonic-gate clientp->ic_recv_cb_arg))
5310Sstevel@tonic-gate
5320Sstevel@tonic-gate /*
5330Sstevel@tonic-gate * if using the default QP handle, remove the callback from
5340Sstevel@tonic-gate * the client context
5350Sstevel@tonic-gate */
5360Sstevel@tonic-gate clientp->ic_recv_cb = NULL;
5370Sstevel@tonic-gate clientp->ic_recv_cb_arg = NULL;
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate ASSERT((clientp->ic_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0);
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
5420Sstevel@tonic-gate } else {
5430Sstevel@tonic-gate ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
5440Sstevel@tonic-gate
5450Sstevel@tonic-gate mutex_enter(&qpp->isq_mutex);
5460Sstevel@tonic-gate
5470Sstevel@tonic-gate /* check if callback has not been registered */
5480Sstevel@tonic-gate if (qpp->isq_recv_cb == NULL) {
5490Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
5500Sstevel@tonic-gate (void) sprintf(errmsg, "no cb exists");
5510Sstevel@tonic-gate error = B_TRUE;
5520Sstevel@tonic-gate status = IBMF_CB_NOT_REGISTERED;
5530Sstevel@tonic-gate goto bail;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate
5560Sstevel@tonic-gate /*
5570Sstevel@tonic-gate * if an unsolicited MAD just arrived for this
5580Sstevel@tonic-gate * client on the alternate QP, wait for it to be processed
5590Sstevel@tonic-gate */
5600Sstevel@tonic-gate while (qpp->isq_flags & IBMF_CLIENT_RECV_CB_ACTIVE) {
5610Sstevel@tonic-gate qpp->isq_flags |= IBMF_CLIENT_TEAR_DOWN_CB;
5620Sstevel@tonic-gate cv_wait(&qpp->isq_recv_cb_teardown_cv,
5630Sstevel@tonic-gate &qpp->isq_mutex);
5640Sstevel@tonic-gate qpp->isq_flags &= ~IBMF_CLIENT_TEAR_DOWN_CB;
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate
5670Sstevel@tonic-gate /*
5680Sstevel@tonic-gate * if using an alternate QP handle, remove the callback from
5690Sstevel@tonic-gate * the alternate QP context
5700Sstevel@tonic-gate */
5710Sstevel@tonic-gate qpp->isq_recv_cb = NULL;
5720Sstevel@tonic-gate qpp->isq_recv_cb_arg = NULL;
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate ASSERT((qpp->isq_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0);
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate bail:
5800Sstevel@tonic-gate if (error) {
5810Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
5820Sstevel@tonic-gate ibmf_tear_down_async_cb_err, IBMF_TNF_ERROR, "",
5830Sstevel@tonic-gate "ibmf_tear_down_async_cb(): %s\n", tnf_string, msg, errmsg);
5840Sstevel@tonic-gate }
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_tear_down_async_cb_end,
5870Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_tear_down_async_cb() exit\n");
5880Sstevel@tonic-gate
5890Sstevel@tonic-gate return (status);
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate int
ibmf_alloc_msg(ibmf_handle_t ibmf_handle,int flag,ibmf_msg_t ** ibmf_msgpp)5940Sstevel@tonic-gate ibmf_alloc_msg(ibmf_handle_t ibmf_handle, int flag, ibmf_msg_t **ibmf_msgpp)
5950Sstevel@tonic-gate {
5960Sstevel@tonic-gate ibmf_msg_impl_t *ibmf_msg_impl;
5970Sstevel@tonic-gate ibmf_client_t *clientp;
5980Sstevel@tonic-gate int km_flags;
5990Sstevel@tonic-gate boolean_t error = B_FALSE;
6000Sstevel@tonic-gate int status = IBMF_SUCCESS;
6010Sstevel@tonic-gate char errmsg[128];
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate clientp = (ibmf_client_t *)ibmf_handle;
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_msg_start,
6060Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_alloc_msg() enter, "
6070Sstevel@tonic-gate "ibmf_handle = %p, flags = 0x%x\n",
6080Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle, tnf_uint, flag, flag);
6090Sstevel@tonic-gate
6100Sstevel@tonic-gate /* check for null ibmf_handle and ibmf_msgpp */
6110Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_msgpp == NULL)) {
6120Sstevel@tonic-gate (void) sprintf(errmsg,
6130Sstevel@tonic-gate "invalid argument, NULL pointer argument");
6140Sstevel@tonic-gate error = B_TRUE;
6150Sstevel@tonic-gate status = IBMF_INVALID_ARG;
6160Sstevel@tonic-gate goto bail;
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate
6190Sstevel@tonic-gate /* validate ibmf_handle */
6200Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
6210Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
6220Sstevel@tonic-gate error = B_TRUE;
6230Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
6240Sstevel@tonic-gate goto bail;
6250Sstevel@tonic-gate }
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate /* check signature */
6280Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
6290Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
6300Sstevel@tonic-gate error = B_TRUE;
6310Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
6320Sstevel@tonic-gate goto bail;
6330Sstevel@tonic-gate }
6340Sstevel@tonic-gate
6350Sstevel@tonic-gate /* validate flag */
6360Sstevel@tonic-gate if (flag != IBMF_ALLOC_SLEEP && flag != IBMF_ALLOC_NOSLEEP) {
6370Sstevel@tonic-gate (void) sprintf(errmsg, "invalid flags, flags = 0x%x", flag);
6380Sstevel@tonic-gate error = B_TRUE;
6390Sstevel@tonic-gate status = IBMF_BAD_FLAGS;
6400Sstevel@tonic-gate goto bail;
6410Sstevel@tonic-gate }
6420Sstevel@tonic-gate
6430Sstevel@tonic-gate /* set flags for kmem allocaton */
6440Sstevel@tonic-gate km_flags = (flag == IBMF_ALLOC_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl))
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate /* call the internal function to allocate the IBMF message context */
6490Sstevel@tonic-gate status = ibmf_i_alloc_msg(clientp, &ibmf_msg_impl, km_flags);
6500Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
6510Sstevel@tonic-gate mutex_enter(&clientp->ic_kstat_mutex);
6520Sstevel@tonic-gate IBMF_ADD32_KSTATS(clientp, msg_allocs_failed, 1);
6530Sstevel@tonic-gate mutex_exit(&clientp->ic_kstat_mutex);
6540Sstevel@tonic-gate (void) sprintf(errmsg, "message allocation failure");
6550Sstevel@tonic-gate error = B_TRUE;
6560Sstevel@tonic-gate goto bail;
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate
6590Sstevel@tonic-gate /* increment counter and kstats for number of allocated messages */
6600Sstevel@tonic-gate mutex_enter(&clientp->ic_mutex);
6610Sstevel@tonic-gate clientp->ic_msgs_alloced++;
6620Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
6630Sstevel@tonic-gate mutex_enter(&clientp->ic_kstat_mutex);
6640Sstevel@tonic-gate IBMF_ADD32_KSTATS(clientp, msgs_alloced, 1);
6650Sstevel@tonic-gate mutex_exit(&clientp->ic_kstat_mutex);
6660Sstevel@tonic-gate
6670Sstevel@tonic-gate /* initialize the msg */
6680Sstevel@tonic-gate ibmf_msg_impl->im_client = clientp;
6690Sstevel@tonic-gate cv_init(&ibmf_msg_impl->im_trans_cv, NULL, CV_DRIVER, NULL);
6700Sstevel@tonic-gate mutex_init(&ibmf_msg_impl->im_mutex, NULL, MUTEX_DRIVER, NULL);
6710Sstevel@tonic-gate *ibmf_msgpp = (ibmf_msg_t *)ibmf_msg_impl;
6720Sstevel@tonic-gate
6730Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl))
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate bail:
6760Sstevel@tonic-gate if (error) {
6770Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
6780Sstevel@tonic-gate ibmf_alloc_msg_err, IBMF_TNF_ERROR, "",
6790Sstevel@tonic-gate "ibmf_alloc_msg(): %s\n", tnf_string, msg, errmsg);
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_msg_end,
6830Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_alloc_msg() exit\n");
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate return (status);
6860Sstevel@tonic-gate }
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate int
ibmf_free_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t ** ibmf_msgpp)6900Sstevel@tonic-gate ibmf_free_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp)
6910Sstevel@tonic-gate {
6920Sstevel@tonic-gate ibmf_client_t *clientp;
6930Sstevel@tonic-gate ibmf_msg_impl_t *ibmf_msg_impl;
6940Sstevel@tonic-gate boolean_t error = B_FALSE;
6950Sstevel@tonic-gate int status = IBMF_SUCCESS;
6960Sstevel@tonic-gate char errmsg[128];
6970Sstevel@tonic-gate timeout_id_t msg_rp_set_id, msg_tr_set_id;
6980Sstevel@tonic-gate timeout_id_t msg_rp_unset_id, msg_tr_unset_id;
6990Sstevel@tonic-gate
7000Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_msg_start,
7010Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_free_msg() enter, " "ibmf_handle = %p\n",
7020Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle);
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate /* check for null ibmf_handle and ibmf_msgpp */
7050Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_msgpp == NULL)) {
7060Sstevel@tonic-gate (void) sprintf(errmsg,
7070Sstevel@tonic-gate "invalid argument, NULL pointer argument");
7080Sstevel@tonic-gate error = B_TRUE;
7090Sstevel@tonic-gate status = IBMF_INVALID_ARG;
7100Sstevel@tonic-gate goto bail;
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate /* validate ibmf_handle */
7140Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
7150Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
7160Sstevel@tonic-gate error = B_TRUE;
7170Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
7180Sstevel@tonic-gate goto bail;
7190Sstevel@tonic-gate }
7200Sstevel@tonic-gate
7210Sstevel@tonic-gate ibmf_msg_impl = (ibmf_msg_impl_t *)*ibmf_msgpp;
7220Sstevel@tonic-gate
7230Sstevel@tonic-gate /* check for null message pointer */
7240Sstevel@tonic-gate if (ibmf_msg_impl == NULL) {
7250Sstevel@tonic-gate (void) sprintf(errmsg, "null message");
7260Sstevel@tonic-gate error = B_TRUE;
7270Sstevel@tonic-gate status = IBMF_FAILURE;
7280Sstevel@tonic-gate goto bail;
7290Sstevel@tonic-gate }
7300Sstevel@tonic-gate
7310Sstevel@tonic-gate mutex_enter(&ibmf_msg_impl->im_mutex);
7320Sstevel@tonic-gate
7330Sstevel@tonic-gate /* check if message context flags indicate a busy message */
7340Sstevel@tonic-gate if (ibmf_msg_impl->im_flags & IBMF_MSG_FLAGS_BUSY) {
7350Sstevel@tonic-gate mutex_exit(&ibmf_msg_impl->im_mutex);
7360Sstevel@tonic-gate (void) sprintf(errmsg, "message in use");
7370Sstevel@tonic-gate error = B_TRUE;
7380Sstevel@tonic-gate status = IBMF_BUSY;
7390Sstevel@tonic-gate goto bail;
7400Sstevel@tonic-gate }
7410Sstevel@tonic-gate
7420Sstevel@tonic-gate ASSERT((ibmf_msg_impl->im_flags & IBMF_MSG_FLAGS_ON_LIST) == 0);
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate /* Initialize the timer ID holders */
7450Sstevel@tonic-gate msg_rp_set_id = msg_tr_set_id = 0;
7460Sstevel@tonic-gate msg_rp_unset_id = msg_tr_unset_id = 0;
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate /* Clear any timers that are still set */
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate if (ibmf_msg_impl->im_rp_timeout_id != 0) {
7510Sstevel@tonic-gate msg_rp_set_id = ibmf_msg_impl->im_rp_timeout_id;
7520Sstevel@tonic-gate ibmf_msg_impl->im_rp_timeout_id = 0;
7530Sstevel@tonic-gate }
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate if (ibmf_msg_impl->im_tr_timeout_id != 0) {
7560Sstevel@tonic-gate msg_tr_set_id = ibmf_msg_impl->im_tr_timeout_id;
7570Sstevel@tonic-gate ibmf_msg_impl->im_tr_timeout_id = 0;
7580Sstevel@tonic-gate }
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate if (ibmf_msg_impl->im_rp_unset_timeout_id != 0) {
7610Sstevel@tonic-gate msg_rp_unset_id = ibmf_msg_impl->im_rp_unset_timeout_id;
7620Sstevel@tonic-gate ibmf_msg_impl->im_rp_unset_timeout_id = 0;
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate
7650Sstevel@tonic-gate if (ibmf_msg_impl->im_tr_unset_timeout_id != 0) {
7660Sstevel@tonic-gate msg_tr_unset_id = ibmf_msg_impl->im_tr_unset_timeout_id;
7670Sstevel@tonic-gate ibmf_msg_impl->im_tr_unset_timeout_id = 0;
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate /* mark the message context flags to indicate a freed message */
7710Sstevel@tonic-gate ibmf_msg_impl->im_flags |= IBMF_MSG_FLAGS_FREE;
7720Sstevel@tonic-gate
7730Sstevel@tonic-gate mutex_exit(&ibmf_msg_impl->im_mutex);
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate /* cast pointer to client context */
7760Sstevel@tonic-gate clientp = (ibmf_client_t *)ibmf_handle;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate /* check signature */
7790Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
7800Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
7810Sstevel@tonic-gate error = B_TRUE;
7820Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
7830Sstevel@tonic-gate goto bail;
7840Sstevel@tonic-gate }
7850Sstevel@tonic-gate
7860Sstevel@tonic-gate /* Clear the timers */
7870Sstevel@tonic-gate if (msg_rp_unset_id != 0) {
7880Sstevel@tonic-gate (void) untimeout(msg_rp_unset_id);
7890Sstevel@tonic-gate }
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate if (msg_tr_unset_id != 0) {
7920Sstevel@tonic-gate (void) untimeout(msg_tr_unset_id);
7930Sstevel@tonic-gate }
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate if (msg_rp_set_id != 0) {
7960Sstevel@tonic-gate (void) untimeout(msg_rp_set_id);
7970Sstevel@tonic-gate }
7980Sstevel@tonic-gate
7990Sstevel@tonic-gate if (msg_tr_set_id != 0) {
8000Sstevel@tonic-gate (void) untimeout(msg_tr_set_id);
8010Sstevel@tonic-gate }
8020Sstevel@tonic-gate
8030Sstevel@tonic-gate /* destroy the condition variables */
8040Sstevel@tonic-gate cv_destroy(&ibmf_msg_impl->im_trans_cv);
8050Sstevel@tonic-gate
8060Sstevel@tonic-gate /* decrement counter and kstats for number of allocated messages */
8070Sstevel@tonic-gate mutex_enter(&clientp->ic_mutex);
8080Sstevel@tonic-gate clientp->ic_msgs_alloced--;
8090Sstevel@tonic-gate mutex_exit(&clientp->ic_mutex);
8100Sstevel@tonic-gate mutex_enter(&clientp->ic_kstat_mutex);
8110Sstevel@tonic-gate IBMF_SUB32_KSTATS(clientp, msgs_alloced, 1);
8120Sstevel@tonic-gate mutex_exit(&clientp->ic_kstat_mutex);
8130Sstevel@tonic-gate
8140Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ibmf_msg_impl,
8150Sstevel@tonic-gate ibmf_msg_impl->im_msgbufs_recv,
8160Sstevel@tonic-gate ibmf_msg_impl->im_msgbufs_send))
8170Sstevel@tonic-gate
8180Sstevel@tonic-gate /* call the internal function to free the message context */
8190Sstevel@tonic-gate ibmf_i_free_msg(ibmf_msg_impl);
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate *ibmf_msgpp = NULL;
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate bail:
8240Sstevel@tonic-gate if (error) {
8250Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
8260Sstevel@tonic-gate ibmf_free_msg_err, IBMF_TNF_ERROR, "",
8270Sstevel@tonic-gate "ibmf_free_msg(): %s\n", tnf_string, msg, errmsg);
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate
8300Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_msg_end,
8310Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_free_msg() exit\n");
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate return (status);
8340Sstevel@tonic-gate }
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate /* ARGSUSED */
8380Sstevel@tonic-gate int
ibmf_msg_transport(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t ibmf_qp_handle,ibmf_msg_t * msgp,ibmf_retrans_t * retrans,ibmf_msg_cb_t msg_cb,void * msg_cb_args,uint_t flags)8390Sstevel@tonic-gate ibmf_msg_transport(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
8400Sstevel@tonic-gate ibmf_msg_t *msgp, ibmf_retrans_t *retrans, ibmf_msg_cb_t msg_cb,
8410Sstevel@tonic-gate void *msg_cb_args, uint_t flags)
8420Sstevel@tonic-gate {
8430Sstevel@tonic-gate ibmf_client_t *clientp;
8440Sstevel@tonic-gate ibmf_msg_impl_t *msgimplp;
8450Sstevel@tonic-gate boolean_t blocking, loopback, error = B_FALSE;
8460Sstevel@tonic-gate int status = IBMF_SUCCESS;
8470Sstevel@tonic-gate sm_dr_mad_hdr_t *dr_hdr;
8480Sstevel@tonic-gate char errmsg[128];
8490Sstevel@tonic-gate
8500Sstevel@tonic-gate IBMF_TRACE_5(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_msg_transport_start,
8510Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_msg_transport() enter, "
8520Sstevel@tonic-gate "ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x "
8530Sstevel@tonic-gate "msgp = 0x%p, retrans = 0x%p\n",
8540Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle,
8550Sstevel@tonic-gate tnf_opaque, ibmf_qp_handle, ibmf_qp_handle, tnf_uint, flags, flags,
8560Sstevel@tonic-gate tnf_opaque, msgp, msgp, tnf_opaque, retrans, retrans);
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*msgp,*msgimplp))
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate /* check for null ibmf_handle and msgp */
8610Sstevel@tonic-gate if ((ibmf_handle == NULL) || (msgp == NULL)) {
8620Sstevel@tonic-gate (void) sprintf(errmsg,
8630Sstevel@tonic-gate "invalid argument, NULL pointer argument");
8640Sstevel@tonic-gate error = B_TRUE;
8650Sstevel@tonic-gate status = IBMF_INVALID_ARG;
8660Sstevel@tonic-gate goto bail;
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate
8690Sstevel@tonic-gate /* validate ibmf_handle */
8700Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
8710Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
8720Sstevel@tonic-gate error = B_TRUE;
8730Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
8740Sstevel@tonic-gate goto bail;
8750Sstevel@tonic-gate }
8760Sstevel@tonic-gate
8770Sstevel@tonic-gate /* validate ibmf_qp_handle */
8780Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
8790Sstevel@tonic-gate IBMF_SUCCESS) {
8800Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
8810Sstevel@tonic-gate error = B_TRUE;
8820Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
8830Sstevel@tonic-gate goto bail;
8840Sstevel@tonic-gate }
8850Sstevel@tonic-gate
8860Sstevel@tonic-gate clientp = (ibmf_client_t *)ibmf_handle;
8870Sstevel@tonic-gate
8880Sstevel@tonic-gate /* check signature */
8890Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
8900Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
8910Sstevel@tonic-gate error = B_TRUE;
8920Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
8930Sstevel@tonic-gate goto bail;
8940Sstevel@tonic-gate }
8950Sstevel@tonic-gate
8960Sstevel@tonic-gate /*
8970Sstevel@tonic-gate * Check the validity of the pkey and qkey in the posted packet
8980Sstevel@tonic-gate * For special QPs do the check for QP1 only
8990Sstevel@tonic-gate * For the alternate qps, the pkey and qkey should match the
9000Sstevel@tonic-gate * pkey and qkey maintained in the ibmf cached qp context
9010Sstevel@tonic-gate */
9020Sstevel@tonic-gate if ((ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) &&
9030Sstevel@tonic-gate ((clientp->ic_client_info.client_class != SUBN_AGENT) &&
904*12787SLida.Horn@Oracle.COM (clientp->ic_client_info.client_class != SUBN_ADM_AGENT) &&
9050Sstevel@tonic-gate (clientp->ic_client_info.client_class != SUBN_MANAGER))) {
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate if ((msgp->im_local_addr.ia_p_key != IBMF_P_KEY_DEF_FULL) &&
9080Sstevel@tonic-gate (msgp->im_local_addr.ia_p_key != IBMF_P_KEY_DEF_LIMITED)) {
9090Sstevel@tonic-gate (void) sprintf(errmsg,
9100Sstevel@tonic-gate "PKey in packet not default PKey");
9110Sstevel@tonic-gate error = B_TRUE;
9120Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
9130Sstevel@tonic-gate goto bail;
9140Sstevel@tonic-gate }
9150Sstevel@tonic-gate
9160Sstevel@tonic-gate if (msgp->im_local_addr.ia_q_key != IBMF_MGMT_Q_KEY) {
9170Sstevel@tonic-gate (void) sprintf(errmsg, "QKey in packet not Mgt QKey");
9180Sstevel@tonic-gate error = B_TRUE;
9190Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
9200Sstevel@tonic-gate goto bail;
9210Sstevel@tonic-gate }
9220Sstevel@tonic-gate } else if (ibmf_qp_handle != IBMF_QP_HANDLE_DEFAULT) {
9230Sstevel@tonic-gate ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate /* alternate QP context */
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate mutex_enter(&qpp->isq_mutex);
9280Sstevel@tonic-gate
9290Sstevel@tonic-gate if (msgp->im_local_addr.ia_p_key != qpp->isq_pkey) {
9300Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
9310Sstevel@tonic-gate (void) sprintf(errmsg, "PKey in packet does not match "
9320Sstevel@tonic-gate "PKey in the QP context");
9330Sstevel@tonic-gate error = B_TRUE;
9340Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
9350Sstevel@tonic-gate goto bail;
9360Sstevel@tonic-gate }
9370Sstevel@tonic-gate
9380Sstevel@tonic-gate if (msgp->im_local_addr.ia_q_key != qpp->isq_qkey) {
9390Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
9400Sstevel@tonic-gate (void) sprintf(errmsg, "QKey in packet does not match "
9410Sstevel@tonic-gate "QKey in the QP context");
9420Sstevel@tonic-gate error = B_TRUE;
9430Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
9440Sstevel@tonic-gate goto bail;
9450Sstevel@tonic-gate }
9460Sstevel@tonic-gate
9470Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
9480Sstevel@tonic-gate }
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate msgimplp = (ibmf_msg_impl_t *)msgp;
9510Sstevel@tonic-gate
9520Sstevel@tonic-gate ASSERT(msgimplp->im_client != NULL);
9530Sstevel@tonic-gate ASSERT(msgimplp->im_client == clientp);
9540Sstevel@tonic-gate
9550Sstevel@tonic-gate msgimplp->im_transp_op_flags = flags;
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate mutex_enter(&msgimplp->im_mutex);
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
9600Sstevel@tonic-gate if (msgimplp->im_msgbufs_send.im_bufs_mad_hdr == NULL) {
9610Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
9620Sstevel@tonic-gate (void) sprintf(errmsg, "Send buffer MAD header data "
9630Sstevel@tonic-gate "not provided for special QP");
9640Sstevel@tonic-gate error = B_TRUE;
9650Sstevel@tonic-gate status = IBMF_BAD_SIZE;
9660Sstevel@tonic-gate goto bail;
9670Sstevel@tonic-gate }
9680Sstevel@tonic-gate } else {
9690Sstevel@tonic-gate ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle;
9700Sstevel@tonic-gate
9710Sstevel@tonic-gate mutex_enter(&qpp->isq_mutex);
9720Sstevel@tonic-gate
9730Sstevel@tonic-gate if (((qpp->isq_flags & IBMF_RAW_ONLY) == 0) &&
9740Sstevel@tonic-gate (msgimplp->im_msgbufs_send.im_bufs_mad_hdr == NULL)) {
9750Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
9760Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
9770Sstevel@tonic-gate (void) sprintf(errmsg, "Send buffer MAD header data "
9780Sstevel@tonic-gate "not provided for alternate QP");
9790Sstevel@tonic-gate error = B_TRUE;
9800Sstevel@tonic-gate status = IBMF_BAD_SIZE;
9810Sstevel@tonic-gate goto bail;
9820Sstevel@tonic-gate }
9830Sstevel@tonic-gate mutex_exit(&qpp->isq_mutex);
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate
9860Sstevel@tonic-gate /* check if client has freed the message by calling ibmf_free_msg() */
9870Sstevel@tonic-gate if (msgimplp->im_flags & IBMF_MSG_FLAGS_FREE) {
9880Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
9890Sstevel@tonic-gate (void) sprintf(errmsg, "Message is being freed");
9900Sstevel@tonic-gate error = B_TRUE;
9910Sstevel@tonic-gate status = IBMF_BUSY;
9920Sstevel@tonic-gate goto bail;
9930Sstevel@tonic-gate }
9940Sstevel@tonic-gate
9950Sstevel@tonic-gate /*
9960Sstevel@tonic-gate * check if the message is already in use in an
9970Sstevel@tonic-gate * ibmf_msg_transport() call
9980Sstevel@tonic-gate */
9990Sstevel@tonic-gate if (msgimplp->im_flags & IBMF_MSG_FLAGS_BUSY) {
10000Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
10010Sstevel@tonic-gate (void) sprintf(errmsg,
10020Sstevel@tonic-gate "Message is being processed by an other thread");
10030Sstevel@tonic-gate error = B_TRUE;
10040Sstevel@tonic-gate status = IBMF_BUSY;
10050Sstevel@tonic-gate goto bail;
10060Sstevel@tonic-gate }
10070Sstevel@tonic-gate
10080Sstevel@tonic-gate msgimplp->im_flags = IBMF_MSG_FLAGS_BUSY;
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
10110Sstevel@tonic-gate
10120Sstevel@tonic-gate /* check for the Directed Route SMP loopback case */
10130Sstevel@tonic-gate loopback = B_FALSE;
10140Sstevel@tonic-gate dr_hdr = (sm_dr_mad_hdr_t *)msgimplp->im_msgbufs_send.im_bufs_mad_hdr;
10150Sstevel@tonic-gate if ((dr_hdr->MgmtClass == MAD_MGMT_CLASS_SUBN_DIRECT_ROUTE) &&
10160Sstevel@tonic-gate (dr_hdr->HopCount == 0)) {
10170Sstevel@tonic-gate loopback = B_TRUE;
10180Sstevel@tonic-gate }
10190Sstevel@tonic-gate
10200Sstevel@tonic-gate /* check for and perform DR loopback on tavor */
10210Sstevel@tonic-gate status = ibmf_i_check_for_loopback(msgimplp, msg_cb, msg_cb_args,
10220Sstevel@tonic-gate retrans, &loopback);
10230Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
10240Sstevel@tonic-gate (void) sprintf(errmsg, "dr_loopback_check failed");
10250Sstevel@tonic-gate error = B_TRUE;
10260Sstevel@tonic-gate mutex_enter(&msgimplp->im_mutex);
10270Sstevel@tonic-gate msgimplp->im_flags &= ~IBMF_MSG_FLAGS_BUSY;
10280Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
10290Sstevel@tonic-gate goto bail;
10300Sstevel@tonic-gate }
10310Sstevel@tonic-gate if (loopback == B_TRUE) {
10320Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
10330Sstevel@tonic-gate ibmf_msg_transport_end, IBMF_TNF_TRACE, "",
10340Sstevel@tonic-gate "ibmf_msg_transport() exit, dr_loopback ok\n");
10350Sstevel@tonic-gate return (IBMF_SUCCESS);
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate if (msg_cb == NULL) {
10390Sstevel@tonic-gate blocking = B_TRUE;
10400Sstevel@tonic-gate } else {
10410Sstevel@tonic-gate blocking = B_FALSE;
10420Sstevel@tonic-gate }
10430Sstevel@tonic-gate
10440Sstevel@tonic-gate /* initialize the message context */
10450Sstevel@tonic-gate ibmf_i_init_msg(msgimplp, msg_cb, msg_cb_args, retrans, blocking);
10460Sstevel@tonic-gate
10470Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*msgp,*msgimplp))
10480Sstevel@tonic-gate
10490Sstevel@tonic-gate /* call the internal function to transport the message */
10500Sstevel@tonic-gate status = ibmf_i_msg_transport(clientp, ibmf_qp_handle, msgimplp,
10510Sstevel@tonic-gate blocking);
10520Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
10530Sstevel@tonic-gate (void) sprintf(errmsg, "message transport failed");
10540Sstevel@tonic-gate error = B_TRUE;
10550Sstevel@tonic-gate mutex_enter(&msgimplp->im_mutex);
10560Sstevel@tonic-gate msgimplp->im_flags &= ~IBMF_MSG_FLAGS_BUSY;
10570Sstevel@tonic-gate mutex_exit(&msgimplp->im_mutex);
10580Sstevel@tonic-gate goto bail;
10590Sstevel@tonic-gate }
10600Sstevel@tonic-gate
10610Sstevel@tonic-gate bail:
10620Sstevel@tonic-gate if (error) {
10630Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
10640Sstevel@tonic-gate ibmf_msg_transport_err, IBMF_TNF_ERROR, "",
10650Sstevel@tonic-gate "ibmf_msg_transport(): %s\n", tnf_string, msg, errmsg);
10660Sstevel@tonic-gate }
10670Sstevel@tonic-gate
10680Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_msg_transport_end,
10690Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_msg_transport() exit\n");
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate return (status);
10720Sstevel@tonic-gate }
10730Sstevel@tonic-gate
10740Sstevel@tonic-gate
10750Sstevel@tonic-gate /* ARGSUSED */
10760Sstevel@tonic-gate int
ibmf_alloc_qp(ibmf_handle_t ibmf_handle,ib_pkey_t p_key,ib_qkey_t q_key,uint_t flags,ibmf_qp_handle_t * ibmf_qp_handlep)10770Sstevel@tonic-gate ibmf_alloc_qp(ibmf_handle_t ibmf_handle, ib_pkey_t p_key, ib_qkey_t q_key,
10780Sstevel@tonic-gate uint_t flags, ibmf_qp_handle_t *ibmf_qp_handlep)
10790Sstevel@tonic-gate {
10800Sstevel@tonic-gate ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
10810Sstevel@tonic-gate uint_t alloc_flags;
10820Sstevel@tonic-gate ibmf_alt_qp_t *qp_ctx;
10830Sstevel@tonic-gate boolean_t error = B_FALSE;
10840Sstevel@tonic-gate int status = IBMF_SUCCESS;
10850Sstevel@tonic-gate char errmsg[128];
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_qp_start,
10880Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_alloc_qp() enter, "
10890Sstevel@tonic-gate "ibmf_handlep = %p, p_key = 0x%x, q_key = 0x%x\n",
10900Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle,
10910Sstevel@tonic-gate tnf_uint, pkey, p_key, tnf_uint, qkey, q_key);
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate /* check for null ibmf_handle and ibmf_qp_handle */
10940Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_qp_handlep == NULL)) {
10950Sstevel@tonic-gate (void) sprintf(errmsg,
10960Sstevel@tonic-gate "invalid argument, NULL pointer argument");
10970Sstevel@tonic-gate error = B_TRUE;
10980Sstevel@tonic-gate status = IBMF_INVALID_ARG;
10990Sstevel@tonic-gate goto bail;
11000Sstevel@tonic-gate }
11010Sstevel@tonic-gate
11020Sstevel@tonic-gate /* validate ibmf_handle */
11030Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
11040Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
11050Sstevel@tonic-gate error = B_TRUE;
11060Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
11070Sstevel@tonic-gate goto bail;
11080Sstevel@tonic-gate }
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate /* check signature */
11110Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
11120Sstevel@tonic-gate (void) sprintf(errmsg, "bad signature");
11130Sstevel@tonic-gate error = B_TRUE;
11140Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
11150Sstevel@tonic-gate goto bail;
11160Sstevel@tonic-gate }
11170Sstevel@tonic-gate
11180Sstevel@tonic-gate /* validate PKey */
11190Sstevel@tonic-gate if (IBMF_INVALID_PKEY(p_key)) {
11200Sstevel@tonic-gate (void) sprintf(errmsg, "invalid value in p_key argument");
11210Sstevel@tonic-gate error = B_TRUE;
11220Sstevel@tonic-gate status = IBMF_INVALID_ARG;
11230Sstevel@tonic-gate goto bail;
11240Sstevel@tonic-gate }
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate if (((flags & IBMF_ALT_QP_MAD_NO_RMPP) == 0) &&
11270Sstevel@tonic-gate ((flags & IBMF_ALT_QP_MAD_RMPP) == 0) &&
11280Sstevel@tonic-gate ((flags & IBMF_ALT_QP_RAW_ONLY) == 0)) {
11290Sstevel@tonic-gate (void) sprintf(errmsg, "invalid flags combination");
11300Sstevel@tonic-gate error = B_TRUE;
11310Sstevel@tonic-gate status = IBMF_BAD_FLAGS;
11320Sstevel@tonic-gate goto bail;
11330Sstevel@tonic-gate }
11340Sstevel@tonic-gate
11350Sstevel@tonic-gate alloc_flags = IBMF_ALLOC_SLEEP;
11360Sstevel@tonic-gate
11370Sstevel@tonic-gate /* call the internal function to allocate the alternate QP context */
11380Sstevel@tonic-gate status = ibmf_i_alloc_qp(clientp, p_key, q_key, alloc_flags,
11390Sstevel@tonic-gate ibmf_qp_handlep);
11400Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
11410Sstevel@tonic-gate mutex_enter(&clientp->ic_kstat_mutex);
11420Sstevel@tonic-gate IBMF_ADD32_KSTATS(clientp, alt_qp_allocs_failed, 1);
11430Sstevel@tonic-gate mutex_exit(&clientp->ic_kstat_mutex);
11440Sstevel@tonic-gate (void) sprintf(errmsg, "unable to allocate QP");
11450Sstevel@tonic-gate error = B_TRUE;
11460Sstevel@tonic-gate status = IBMF_NO_RESOURCES;
11470Sstevel@tonic-gate goto bail;
11480Sstevel@tonic-gate }
11490Sstevel@tonic-gate
11500Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*qp_ctx))
11510Sstevel@tonic-gate
11520Sstevel@tonic-gate qp_ctx = (ibmf_alt_qp_t *)*ibmf_qp_handlep;
11530Sstevel@tonic-gate
11540Sstevel@tonic-gate /* initialize the alternate qp context */
11550Sstevel@tonic-gate if (flags & IBMF_ALT_QP_MAD_NO_RMPP)
11560Sstevel@tonic-gate qp_ctx->isq_flags |= IBMF_MAD_ONLY;
11570Sstevel@tonic-gate
11580Sstevel@tonic-gate if (flags & IBMF_ALT_QP_RAW_ONLY)
11590Sstevel@tonic-gate qp_ctx->isq_flags |= IBMF_RAW_ONLY;
11600Sstevel@tonic-gate
11610Sstevel@tonic-gate if (flags & IBMF_ALT_QP_MAD_RMPP)
11620Sstevel@tonic-gate qp_ctx->isq_supports_rmpp = B_TRUE;
11630Sstevel@tonic-gate else
11640Sstevel@tonic-gate qp_ctx->isq_supports_rmpp = B_FALSE;
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate bail:
11670Sstevel@tonic-gate if (error) {
11680Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
11690Sstevel@tonic-gate ibmf_alloc_qp_err, IBMF_TNF_ERROR, "",
11700Sstevel@tonic-gate "ibmf_alloc_qp(): %s\n", tnf_string, msg, errmsg);
11710Sstevel@tonic-gate }
11720Sstevel@tonic-gate
11730Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_alloc_qp_end,
11740Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_alloc_qp() exit\n");
11750Sstevel@tonic-gate
11760Sstevel@tonic-gate
11770Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*qp_ctx))
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate return (status);
11800Sstevel@tonic-gate }
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate
11830Sstevel@tonic-gate /* ARGSUSED */
11840Sstevel@tonic-gate int
ibmf_query_qp(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t ibmf_qp_handle,uint_t * qp_num,ib_pkey_t * p_key,ib_qkey_t * q_key,uint8_t * portnum,uint_t flags)11850Sstevel@tonic-gate ibmf_query_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
11860Sstevel@tonic-gate uint_t *qp_num, ib_pkey_t *p_key, ib_qkey_t *q_key, uint8_t *portnum,
11870Sstevel@tonic-gate uint_t flags)
11880Sstevel@tonic-gate {
11890Sstevel@tonic-gate ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
11900Sstevel@tonic-gate ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)ibmf_qp_handle;
11910Sstevel@tonic-gate uint_t query_flags;
11920Sstevel@tonic-gate boolean_t error = B_FALSE;
11930Sstevel@tonic-gate int status = IBMF_SUCCESS;
11940Sstevel@tonic-gate char errmsg[128];
11950Sstevel@tonic-gate
11960Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_query_qp_start,
11970Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_query_qp() enter, "
11980Sstevel@tonic-gate "ibmf_handlep = %p, ibmf_qp_handle = %p\n",
11990Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle,
12000Sstevel@tonic-gate tnf_opaque, ibmf_qp_handle, ibmf_qp_handle);
12010Sstevel@tonic-gate
12020Sstevel@tonic-gate /* check for null args */
12030Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL) ||
12040Sstevel@tonic-gate (qp_num == NULL) || (p_key == NULL) || (q_key == NULL) ||
12050Sstevel@tonic-gate (portnum == NULL)) {
12060Sstevel@tonic-gate (void) sprintf(errmsg,
12070Sstevel@tonic-gate "invalid argument, NULL pointer argument");
12080Sstevel@tonic-gate error = B_TRUE;
12090Sstevel@tonic-gate status = IBMF_INVALID_ARG;
12100Sstevel@tonic-gate goto bail;
12110Sstevel@tonic-gate }
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate /* validate ibmf_handle */
12140Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
12150Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
12160Sstevel@tonic-gate error = B_TRUE;
12170Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
12180Sstevel@tonic-gate goto bail;
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate /* validate ibmf_qp_handle */
12220Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
12230Sstevel@tonic-gate IBMF_SUCCESS) {
12240Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
12250Sstevel@tonic-gate error = B_TRUE;
12260Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
12270Sstevel@tonic-gate goto bail;
12280Sstevel@tonic-gate }
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate /* validate ibmf_qp_handle */
12310Sstevel@tonic-gate if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
12320Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle (default)");
12330Sstevel@tonic-gate error = B_TRUE;
12340Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
12350Sstevel@tonic-gate goto bail;
12360Sstevel@tonic-gate }
12370Sstevel@tonic-gate
12380Sstevel@tonic-gate /* check signature */
12390Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
12400Sstevel@tonic-gate (void) sprintf(errmsg, "bad client signature");
12410Sstevel@tonic-gate error = B_TRUE;
12420Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
12430Sstevel@tonic-gate goto bail;
12440Sstevel@tonic-gate }
12450Sstevel@tonic-gate
12460Sstevel@tonic-gate /* validate client context handle */
12470Sstevel@tonic-gate if (qp_ctx->isq_client_hdl != clientp) {
12480Sstevel@tonic-gate (void) sprintf(errmsg, "bad QP handle");
12490Sstevel@tonic-gate error = B_TRUE;
12500Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
12510Sstevel@tonic-gate goto bail;
12520Sstevel@tonic-gate }
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate query_flags = IBMF_ALLOC_NOSLEEP;
12550Sstevel@tonic-gate
12560Sstevel@tonic-gate /* call the internal function to query the alternate qp */
12570Sstevel@tonic-gate status = ibmf_i_query_qp(ibmf_qp_handle, query_flags, qp_num, p_key,
12580Sstevel@tonic-gate q_key, portnum);
12590Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
12600Sstevel@tonic-gate (void) sprintf(errmsg, "unable to query QP");
12610Sstevel@tonic-gate error = B_TRUE;
12620Sstevel@tonic-gate goto bail;
12630Sstevel@tonic-gate }
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate bail:
12660Sstevel@tonic-gate if (error) {
12670Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
12680Sstevel@tonic-gate ibmf_query_qp_err, IBMF_TNF_ERROR, "",
12690Sstevel@tonic-gate "ibmf_query_qp(): %s\n", tnf_string, msg, errmsg);
12700Sstevel@tonic-gate }
12710Sstevel@tonic-gate
12720Sstevel@tonic-gate IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_query_qp_end,
12730Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_query_qp() exit, qp = %d, "
12740Sstevel@tonic-gate "pkey = 0x%x, qkey = 0x%x\n", tnf_uint, qp_num, *qp_num,
12750Sstevel@tonic-gate tnf_uint, pkey, *p_key, tnf_uint, qkey, *q_key);
12760Sstevel@tonic-gate
12770Sstevel@tonic-gate return (status);
12780Sstevel@tonic-gate }
12790Sstevel@tonic-gate
12800Sstevel@tonic-gate
12810Sstevel@tonic-gate /* ARGSUSED */
12820Sstevel@tonic-gate int
ibmf_modify_qp(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t ibmf_qp_handle,ib_pkey_t p_key,ib_qkey_t q_key,uint_t flags)12830Sstevel@tonic-gate ibmf_modify_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t ibmf_qp_handle,
12840Sstevel@tonic-gate ib_pkey_t p_key, ib_qkey_t q_key, uint_t flags)
12850Sstevel@tonic-gate {
12860Sstevel@tonic-gate ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
12870Sstevel@tonic-gate ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)ibmf_qp_handle;
12880Sstevel@tonic-gate uint_t modify_flags;
12890Sstevel@tonic-gate boolean_t error = B_FALSE;
12900Sstevel@tonic-gate int status = IBMF_SUCCESS;
12910Sstevel@tonic-gate char errmsg[128];
12920Sstevel@tonic-gate
12930Sstevel@tonic-gate IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_modify_qp_start,
12940Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_modify_qp() enter, "
12950Sstevel@tonic-gate "ibmf_handlep = %p, ibmf_qp_handle = %p, pkey = 0x%x, "
12960Sstevel@tonic-gate "qkey = 0x%x\n", tnf_opaque, ibmf_handle, ibmf_handle,
12970Sstevel@tonic-gate tnf_opaque, ibmf_qp_handle, ibmf_qp_handle,
12980Sstevel@tonic-gate tnf_uint, p_key, p_key, tnf_uint, q_key, q_key);
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate /* check for null args */
13010Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL)) {
13020Sstevel@tonic-gate (void) sprintf(errmsg,
13030Sstevel@tonic-gate "invalid argument, NULL pointer argument");
13040Sstevel@tonic-gate error = B_TRUE;
13050Sstevel@tonic-gate status = IBMF_INVALID_ARG;
13060Sstevel@tonic-gate goto bail;
13070Sstevel@tonic-gate }
13080Sstevel@tonic-gate
13090Sstevel@tonic-gate /* validate ibmf_handle */
13100Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
13110Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
13120Sstevel@tonic-gate error = B_TRUE;
13130Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
13140Sstevel@tonic-gate goto bail;
13150Sstevel@tonic-gate }
13160Sstevel@tonic-gate
13170Sstevel@tonic-gate /* validate ibmf_qp_handle */
13180Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, ibmf_qp_handle) !=
13190Sstevel@tonic-gate IBMF_SUCCESS) {
13200Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
13210Sstevel@tonic-gate error = B_TRUE;
13220Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
13230Sstevel@tonic-gate goto bail;
13240Sstevel@tonic-gate }
13250Sstevel@tonic-gate
13260Sstevel@tonic-gate /* validate ibmf_qp_handle */
13270Sstevel@tonic-gate if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
13280Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle (default)");
13290Sstevel@tonic-gate error = B_TRUE;
13300Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
13310Sstevel@tonic-gate goto bail;
13320Sstevel@tonic-gate }
13330Sstevel@tonic-gate
13340Sstevel@tonic-gate /* check signature */
13350Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
13360Sstevel@tonic-gate (void) sprintf(errmsg, "bad client signature");
13370Sstevel@tonic-gate error = B_TRUE;
13380Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
13390Sstevel@tonic-gate goto bail;
13400Sstevel@tonic-gate }
13410Sstevel@tonic-gate
13420Sstevel@tonic-gate /* validate PKey */
13430Sstevel@tonic-gate if (IBMF_INVALID_PKEY(p_key)) {
13440Sstevel@tonic-gate (void) sprintf(errmsg, "invalid value in p_key argument");
13450Sstevel@tonic-gate error = B_TRUE;
13460Sstevel@tonic-gate status = IBMF_INVALID_ARG;
13470Sstevel@tonic-gate goto bail;
13480Sstevel@tonic-gate }
13490Sstevel@tonic-gate
13500Sstevel@tonic-gate if (qp_ctx->isq_client_hdl != clientp) {
13510Sstevel@tonic-gate (void) sprintf(errmsg, "bad QP handle");
13520Sstevel@tonic-gate error = B_TRUE;
13530Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
13540Sstevel@tonic-gate goto bail;
13550Sstevel@tonic-gate }
13560Sstevel@tonic-gate
13570Sstevel@tonic-gate modify_flags = IBMF_ALLOC_SLEEP;
13580Sstevel@tonic-gate
13590Sstevel@tonic-gate /* call the internal function to modify the qp */
13600Sstevel@tonic-gate status = ibmf_i_modify_qp(ibmf_qp_handle, p_key, q_key, modify_flags);
13610Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
13620Sstevel@tonic-gate (void) sprintf(errmsg, "unable to modify QP");
13630Sstevel@tonic-gate error = B_TRUE;
13640Sstevel@tonic-gate goto bail;
13650Sstevel@tonic-gate }
13660Sstevel@tonic-gate
13670Sstevel@tonic-gate bail:
13680Sstevel@tonic-gate if (error) {
13690Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
13700Sstevel@tonic-gate ibmf_modify_qp_err, IBMF_TNF_ERROR, "",
13710Sstevel@tonic-gate "ibmf_modify_qp(): %s\n", tnf_string, msg, errmsg);
13720Sstevel@tonic-gate }
13730Sstevel@tonic-gate
13740Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_modify_qp_end,
13750Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_modify_qp() exit\n");
13760Sstevel@tonic-gate
13770Sstevel@tonic-gate return (status);
13780Sstevel@tonic-gate }
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate /* ARGSUSED */
13810Sstevel@tonic-gate int
ibmf_free_qp(ibmf_handle_t ibmf_handle,ibmf_qp_handle_t * ibmf_qp_handle,uint_t flags)13820Sstevel@tonic-gate ibmf_free_qp(ibmf_handle_t ibmf_handle, ibmf_qp_handle_t *ibmf_qp_handle,
13830Sstevel@tonic-gate uint_t flags)
13840Sstevel@tonic-gate {
13850Sstevel@tonic-gate ibmf_client_t *clientp = (ibmf_client_t *)ibmf_handle;
13860Sstevel@tonic-gate ibmf_alt_qp_t *qp_ctx = (ibmf_alt_qp_t *)*ibmf_qp_handle;
13870Sstevel@tonic-gate uint_t modify_flags;
13880Sstevel@tonic-gate boolean_t error = B_FALSE;
13890Sstevel@tonic-gate int status = IBMF_SUCCESS;
13900Sstevel@tonic-gate char errmsg[128];
13910Sstevel@tonic-gate
13920Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_qp_start,
13930Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_free_qp() enter, "
13940Sstevel@tonic-gate "ibmf_handlep = %p, ibmf_qp_handle = %p\n",
13950Sstevel@tonic-gate tnf_opaque, ibmf_handle, ibmf_handle,
13960Sstevel@tonic-gate tnf_opaque, ibmf_qp_handle, *ibmf_qp_handle);
13970Sstevel@tonic-gate
13980Sstevel@tonic-gate /* check for null args */
13990Sstevel@tonic-gate if ((ibmf_handle == NULL) || (ibmf_qp_handle == NULL)) {
14000Sstevel@tonic-gate (void) sprintf(errmsg,
14010Sstevel@tonic-gate "invalid argument, NULL pointer argument");
14020Sstevel@tonic-gate error = B_TRUE;
14030Sstevel@tonic-gate status = IBMF_INVALID_ARG;
14040Sstevel@tonic-gate goto bail;
14050Sstevel@tonic-gate }
14060Sstevel@tonic-gate
14070Sstevel@tonic-gate /* validate ibmf_handle */
14080Sstevel@tonic-gate if (ibmf_i_is_ibmf_handle_valid(ibmf_handle) != IBMF_SUCCESS) {
14090Sstevel@tonic-gate (void) sprintf(errmsg, "bad ibmf registration handle");
14100Sstevel@tonic-gate error = B_TRUE;
14110Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
14120Sstevel@tonic-gate goto bail;
14130Sstevel@tonic-gate }
14140Sstevel@tonic-gate
14150Sstevel@tonic-gate /* validate ibmf_qp_handle */
14160Sstevel@tonic-gate if (ibmf_i_is_qp_handle_valid(ibmf_handle, *ibmf_qp_handle) !=
14170Sstevel@tonic-gate IBMF_SUCCESS) {
14180Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle");
14190Sstevel@tonic-gate error = B_TRUE;
14200Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
14210Sstevel@tonic-gate goto bail;
14220Sstevel@tonic-gate }
14230Sstevel@tonic-gate
14240Sstevel@tonic-gate /* validate ibmf_qp_handle */
14250Sstevel@tonic-gate if (*ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
14260Sstevel@tonic-gate (void) sprintf(errmsg, "bad qp handle (default)");
14270Sstevel@tonic-gate error = B_TRUE;
14280Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
14290Sstevel@tonic-gate goto bail;
14300Sstevel@tonic-gate }
14310Sstevel@tonic-gate
14320Sstevel@tonic-gate /* check signature */
14330Sstevel@tonic-gate if (IBMF_VERIFY_CLIENT_SIGNATURE(clientp) == B_FALSE) {
14340Sstevel@tonic-gate (void) sprintf(errmsg, "bad client signature");
14350Sstevel@tonic-gate error = B_TRUE;
14360Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
14370Sstevel@tonic-gate goto bail;
14380Sstevel@tonic-gate }
14390Sstevel@tonic-gate
14400Sstevel@tonic-gate /* validate client context handle */
14410Sstevel@tonic-gate if (qp_ctx->isq_client_hdl != clientp) {
14420Sstevel@tonic-gate (void) sprintf(errmsg, "bad QP handle");
14430Sstevel@tonic-gate error = B_TRUE;
14440Sstevel@tonic-gate status = IBMF_BAD_QP_HANDLE;
14450Sstevel@tonic-gate goto bail;
14460Sstevel@tonic-gate }
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate mutex_enter(&qp_ctx->isq_mutex);
14490Sstevel@tonic-gate
14500Sstevel@tonic-gate if (qp_ctx->isq_recv_cb != NULL) {
14510Sstevel@tonic-gate mutex_exit(&qp_ctx->isq_mutex);
14520Sstevel@tonic-gate (void) sprintf(errmsg, "QP busy, callback active");
14530Sstevel@tonic-gate error = B_TRUE;
14540Sstevel@tonic-gate status = IBMF_BUSY;
14550Sstevel@tonic-gate goto bail;
14560Sstevel@tonic-gate }
14570Sstevel@tonic-gate
14580Sstevel@tonic-gate mutex_exit(&qp_ctx->isq_mutex);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate modify_flags = IBMF_ALLOC_SLEEP;
14610Sstevel@tonic-gate
14620Sstevel@tonic-gate status = ibmf_i_free_qp(*ibmf_qp_handle, modify_flags);
14630Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
14640Sstevel@tonic-gate (void) sprintf(errmsg, "unable to free QP");
14650Sstevel@tonic-gate error = B_TRUE;
14660Sstevel@tonic-gate goto bail;
14670Sstevel@tonic-gate }
14680Sstevel@tonic-gate
14690Sstevel@tonic-gate *ibmf_qp_handle = NULL;
14700Sstevel@tonic-gate
14710Sstevel@tonic-gate bail:
14720Sstevel@tonic-gate if (error) {
14730Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
14740Sstevel@tonic-gate ibmf_free_qp_err, IBMF_TNF_ERROR, "",
14750Sstevel@tonic-gate "ibmf_free_qp(): %s\n", tnf_string, msg, errmsg);
14760Sstevel@tonic-gate }
14770Sstevel@tonic-gate
14780Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_free_qp_end,
14790Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_free_qp() exit\n");
14800Sstevel@tonic-gate
14810Sstevel@tonic-gate return (status);
14820Sstevel@tonic-gate }
1483