11bdd6c0eSSue Gleeson /*
21bdd6c0eSSue Gleeson  * CDDL HEADER START
31bdd6c0eSSue Gleeson  *
41bdd6c0eSSue Gleeson  * The contents of this file are subject to the terms of the
51bdd6c0eSSue Gleeson  * Common Development and Distribution License (the "License").
61bdd6c0eSSue Gleeson  * You may not use this file except in compliance with the License.
71bdd6c0eSSue Gleeson  *
81bdd6c0eSSue Gleeson  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91bdd6c0eSSue Gleeson  * or http://www.opensolaris.org/os/licensing.
101bdd6c0eSSue Gleeson  * See the License for the specific language governing permissions
111bdd6c0eSSue Gleeson  * and limitations under the License.
121bdd6c0eSSue Gleeson  *
131bdd6c0eSSue Gleeson  * When distributing Covered Code, include this CDDL HEADER in each
141bdd6c0eSSue Gleeson  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151bdd6c0eSSue Gleeson  * If applicable, add the following below this CDDL HEADER, with the
161bdd6c0eSSue Gleeson  * fields enclosed by brackets "[]" replaced with your own identifying
171bdd6c0eSSue Gleeson  * information: Portions Copyright [yyyy] [name of copyright owner]
181bdd6c0eSSue Gleeson  *
191bdd6c0eSSue Gleeson  * CDDL HEADER END
201bdd6c0eSSue Gleeson  */
211bdd6c0eSSue Gleeson 
221bdd6c0eSSue Gleeson /*
234558d122SViswanathan Kannappan  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
241bdd6c0eSSue Gleeson  */
251bdd6c0eSSue Gleeson 
26*571d0d19SJohn Levon /*
27*571d0d19SJohn Levon  * Copyright 2019, Joyent, Inc.
28*571d0d19SJohn Levon  */
29*571d0d19SJohn Levon 
301bdd6c0eSSue Gleeson /*
311bdd6c0eSSue Gleeson  * IB CM handlers for s Solaris SCSI RDMA Protocol Target (SRP)
321bdd6c0eSSue Gleeson  * transport port provider module for the COMSTAR framework.
331bdd6c0eSSue Gleeson  */
341bdd6c0eSSue Gleeson 
351bdd6c0eSSue Gleeson #include <sys/cpuvar.h>
361bdd6c0eSSue Gleeson #include <sys/types.h>
371bdd6c0eSSue Gleeson #include <sys/conf.h>
381bdd6c0eSSue Gleeson #include <sys/stat.h>
391bdd6c0eSSue Gleeson #include <sys/file.h>
401bdd6c0eSSue Gleeson #include <sys/ddi.h>
411bdd6c0eSSue Gleeson #include <sys/sunddi.h>
421bdd6c0eSSue Gleeson #include <sys/modctl.h>
431bdd6c0eSSue Gleeson #include <sys/sysmacros.h>
441bdd6c0eSSue Gleeson #include <sys/sdt.h>
451bdd6c0eSSue Gleeson #include <sys/taskq.h>
461bdd6c0eSSue Gleeson #include <sys/ib/ibtl/ibti.h>
471bdd6c0eSSue Gleeson 
484558d122SViswanathan Kannappan #include <sys/stmf.h>
494558d122SViswanathan Kannappan #include <sys/stmf_ioctl.h>
504558d122SViswanathan Kannappan #include <sys/portif.h>
511bdd6c0eSSue Gleeson 
521bdd6c0eSSue Gleeson #include "srp.h"
531bdd6c0eSSue Gleeson #include "srpt_impl.h"
541bdd6c0eSSue Gleeson #include "srpt_cm.h"
551bdd6c0eSSue Gleeson #include "srpt_stp.h"
561bdd6c0eSSue Gleeson #include "srpt_ch.h"
571bdd6c0eSSue Gleeson 
581bdd6c0eSSue Gleeson extern uint16_t srpt_send_msg_depth;
591bdd6c0eSSue Gleeson extern srpt_ctxt_t  *srpt_ctxt;
601bdd6c0eSSue Gleeson 
611bdd6c0eSSue Gleeson /*
621bdd6c0eSSue Gleeson  * srpt_cm_req_hdlr() - Login request
631bdd6c0eSSue Gleeson  *
641bdd6c0eSSue Gleeson  * CM has called back with a CM REQ message associated with an
651bdd6c0eSSue Gleeson  * SRP initiator login request.
661bdd6c0eSSue Gleeson  */
671bdd6c0eSSue Gleeson static ibt_cm_status_t
srpt_cm_req_hdlr(srpt_target_port_t * tgt,ibt_cm_event_t * event,ibt_cm_return_args_t * ret_args,void * ret_priv_data,ibt_priv_data_len_t ret_priv_data_len)681bdd6c0eSSue Gleeson srpt_cm_req_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event,
69*571d0d19SJohn Levon     ibt_cm_return_args_t *ret_args, void *ret_priv_data,
70*571d0d19SJohn Levon     ibt_priv_data_len_t ret_priv_data_len)
711bdd6c0eSSue Gleeson {
721bdd6c0eSSue Gleeson 	ibt_cm_status_t		status;
731bdd6c0eSSue Gleeson 	ibt_cm_req_rcv_t	*req;
741bdd6c0eSSue Gleeson 	srp_login_req_t		login;
751bdd6c0eSSue Gleeson 	srp_login_rej_t		login_rej;
761bdd6c0eSSue Gleeson 	srp_login_rsp_t		login_rsp;
771bdd6c0eSSue Gleeson 	srpt_channel_t		*ch = NULL;
78191c289bSCharles Ting 	char			remote_gid[SRPT_ALIAS_LEN];
79191c289bSCharles Ting 	char			local_gid[SRPT_ALIAS_LEN];
801bdd6c0eSSue Gleeson 
811bdd6c0eSSue Gleeson 	ASSERT(tgt != NULL);
821bdd6c0eSSue Gleeson 	req = &event->cm_event.req;
831bdd6c0eSSue Gleeson 
841bdd6c0eSSue Gleeson 	if (event->cm_priv_data_len <  sizeof (srp_login_req_t)) {
851bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_req_hdlr, IU size expected (>= %d),"
861bdd6c0eSSue Gleeson 		    " received size (%d)", (uint_t)sizeof (srp_login_req_t),
871bdd6c0eSSue Gleeson 		    event->cm_priv_data_len);
881bdd6c0eSSue Gleeson 		return (IBT_CM_REJECT);
891bdd6c0eSSue Gleeson 	}
901bdd6c0eSSue Gleeson 
911bdd6c0eSSue Gleeson 	if (event->cm_priv_data == NULL) {
921bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP private data pointer");
931bdd6c0eSSue Gleeson 		return (IBT_CM_REJECT);
941bdd6c0eSSue Gleeson 	}
951bdd6c0eSSue Gleeson 
961bdd6c0eSSue Gleeson 	if (ret_priv_data_len <  sizeof (srp_login_rej_t)) {
971bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_req_hdlr, return private len too"
981bdd6c0eSSue Gleeson 		    " small (%d)", ret_priv_data_len);
991bdd6c0eSSue Gleeson 		return (IBT_CM_REJECT);
1001bdd6c0eSSue Gleeson 	}
1011bdd6c0eSSue Gleeson 
1021bdd6c0eSSue Gleeson 	if (ret_priv_data == NULL) {
1031bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP return private data"
1041bdd6c0eSSue Gleeson 		    " pointer");
1051bdd6c0eSSue Gleeson 		return (IBT_CM_REJECT);
1061bdd6c0eSSue Gleeson 	}
1071bdd6c0eSSue Gleeson 
1081bdd6c0eSSue Gleeson 	/*
1091bdd6c0eSSue Gleeson 	 * Copy to avoid potential alignment problems, process login
1101bdd6c0eSSue Gleeson 	 * creating a new channel and possibly session.
1111bdd6c0eSSue Gleeson 	 */
1121bdd6c0eSSue Gleeson 	bcopy(event->cm_priv_data, &login,  sizeof (login));
1131bdd6c0eSSue Gleeson 
114191c289bSCharles Ting 	ALIAS_STR(local_gid,
115191c289bSCharles Ting 	    req->req_prim_addr.av_sgid.gid_prefix,
116191c289bSCharles Ting 	    req->req_prim_addr.av_sgid.gid_guid);
117191c289bSCharles Ting 	ALIAS_STR(remote_gid,
118191c289bSCharles Ting 	    req->req_prim_addr.av_dgid.gid_prefix,
119191c289bSCharles Ting 	    req->req_prim_addr.av_dgid.gid_guid);
120191c289bSCharles Ting 
1211bdd6c0eSSue Gleeson 	ch = srpt_stp_login(tgt, &login, &login_rsp,
122191c289bSCharles Ting 	    &login_rej, req->req_prim_hca_port, local_gid, remote_gid);
1231bdd6c0eSSue Gleeson 	if (ch != NULL) {
1241bdd6c0eSSue Gleeson 		bcopy(&login_rsp, ret_priv_data,  SRP_LOGIN_RSP_SIZE);
1251bdd6c0eSSue Gleeson 		ret_args->cm_ret_len = SRP_LOGIN_RSP_SIZE;
1261bdd6c0eSSue Gleeson 
1271bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_req_hdlr, rsp priv len(%d)"
1281bdd6c0eSSue Gleeson 		    " ch created on port(%d)"
1291bdd6c0eSSue Gleeson 		    ", cm_req_hdlr, req ra_out(%d), ra_in(%d)"
1301bdd6c0eSSue Gleeson 		    ", retry(%d)",
1311bdd6c0eSSue Gleeson 		    ret_args->cm_ret_len, req->req_prim_hca_port,
1321bdd6c0eSSue Gleeson 		    req->req_rdma_ra_out, req->req_rdma_ra_in,
1331bdd6c0eSSue Gleeson 		    req->req_retry_cnt);
1341bdd6c0eSSue Gleeson 
1351bdd6c0eSSue Gleeson 		ret_args->cm_ret.rep.cm_channel = ch->ch_chan_hdl;
1361bdd6c0eSSue Gleeson 		ret_args->cm_ret.rep.cm_rdma_ra_out =
1371bdd6c0eSSue Gleeson 		    min(tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
1381bdd6c0eSSue Gleeson 		    req->req_rdma_ra_in);
1391bdd6c0eSSue Gleeson 		ret_args->cm_ret.rep.cm_rdma_ra_in =
1401bdd6c0eSSue Gleeson 		    min(tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
1411bdd6c0eSSue Gleeson 		    req->req_rdma_ra_out);
1421bdd6c0eSSue Gleeson 		ret_args->cm_ret.rep.cm_rnr_retry_cnt = req->req_retry_cnt;
1431bdd6c0eSSue Gleeson 
1441bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_req_hdlr, hca_max_rdma_in_chan (%d)"
1451bdd6c0eSSue Gleeson 		    ", hca_max_rdma_out_chan (%d)"
1461bdd6c0eSSue Gleeson 		    ", updated ra_out(%d), ra_in(%d), retry(%d)",
1471bdd6c0eSSue Gleeson 		    tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
1481bdd6c0eSSue Gleeson 		    tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
1491bdd6c0eSSue Gleeson 		    ret_args->cm_ret.rep.cm_rdma_ra_out,
1501bdd6c0eSSue Gleeson 		    ret_args->cm_ret.rep.cm_rdma_ra_in,
1511bdd6c0eSSue Gleeson 		    ret_args->cm_ret.rep.cm_rnr_retry_cnt);
1521bdd6c0eSSue Gleeson 		status = IBT_CM_ACCEPT;
1531bdd6c0eSSue Gleeson 
1541bdd6c0eSSue Gleeson 	} else {
1551bdd6c0eSSue Gleeson 		bcopy(&login_rej, ret_priv_data,  sizeof (login_rej));
1561bdd6c0eSSue Gleeson 		ret_args->cm_ret_len =  sizeof (login_rej);
1571bdd6c0eSSue Gleeson 		status = IBT_CM_REJECT;
1581bdd6c0eSSue Gleeson 	}
1591bdd6c0eSSue Gleeson 
1601bdd6c0eSSue Gleeson 	return (status);
1611bdd6c0eSSue Gleeson }
1621bdd6c0eSSue Gleeson 
1631bdd6c0eSSue Gleeson /*
1641bdd6c0eSSue Gleeson  * srpt_cm_conn_est_hdlr() - Connection established
1651bdd6c0eSSue Gleeson  *
1661bdd6c0eSSue Gleeson  * CM has called back to inform us that a connection attempt has
1671bdd6c0eSSue Gleeson  * completed (explicit or implicit) and may now be used.
1681bdd6c0eSSue Gleeson  */
1691bdd6c0eSSue Gleeson /* ARGSUSED */
1701bdd6c0eSSue Gleeson static ibt_cm_status_t
srpt_cm_conn_est_hdlr(srpt_target_port_t * tgt,ibt_cm_event_t * event)1711bdd6c0eSSue Gleeson srpt_cm_conn_est_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
1721bdd6c0eSSue Gleeson {
1731bdd6c0eSSue Gleeson 	srpt_channel_t		*ch;
1741bdd6c0eSSue Gleeson 
1751bdd6c0eSSue Gleeson 	ASSERT(tgt != NULL);
1761bdd6c0eSSue Gleeson 	ASSERT(event != NULL);
1771bdd6c0eSSue Gleeson 
1781bdd6c0eSSue Gleeson 	ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
1791bdd6c0eSSue Gleeson 	ASSERT(ch != NULL);
1801bdd6c0eSSue Gleeson 
1811bdd6c0eSSue Gleeson 	SRPT_DPRINTF_L3("cm_conn_est_hdlr, invoked for ch(%p)",
1821bdd6c0eSSue Gleeson 	    (void *)ch);
1831bdd6c0eSSue Gleeson 
1841bdd6c0eSSue Gleeson 	rw_enter(&ch->ch_rwlock, RW_WRITER);
1851bdd6c0eSSue Gleeson 	if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
1861bdd6c0eSSue Gleeson 	    ch->ch_state != SRPT_CHANNEL_CONNECTED) {
1871bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_conn_est_hdlr, invalid ch state (%d)",
1881bdd6c0eSSue Gleeson 		    ch->ch_state);
1891bdd6c0eSSue Gleeson 		rw_exit(&ch->ch_rwlock);
1901bdd6c0eSSue Gleeson 		return (IBT_CM_REJECT);
1911bdd6c0eSSue Gleeson 	}
1921bdd6c0eSSue Gleeson 
1931bdd6c0eSSue Gleeson 	ch->ch_state = SRPT_CHANNEL_CONNECTED;
1941bdd6c0eSSue Gleeson 
1951bdd6c0eSSue Gleeson 	rw_exit(&ch->ch_rwlock);
1961bdd6c0eSSue Gleeson 	return (IBT_CM_ACCEPT);
1971bdd6c0eSSue Gleeson }
1981bdd6c0eSSue Gleeson 
1991bdd6c0eSSue Gleeson /*
2001bdd6c0eSSue Gleeson  * srpt_cm_conn_closed_hdlr() - Channel closed
2011bdd6c0eSSue Gleeson  *
2021bdd6c0eSSue Gleeson  * CM callback indicating a channel has been completely closed.
2031bdd6c0eSSue Gleeson  */
2041bdd6c0eSSue Gleeson /* ARGSUSED */
2051bdd6c0eSSue Gleeson static ibt_cm_status_t
srpt_cm_conn_closed_hdlr(srpt_target_port_t * tgt,ibt_cm_event_t * event)2061bdd6c0eSSue Gleeson srpt_cm_conn_closed_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
2071bdd6c0eSSue Gleeson {
2081bdd6c0eSSue Gleeson 	ibt_cm_status_t		status = IBT_CM_ACCEPT;
2091bdd6c0eSSue Gleeson 	srpt_channel_t		*ch;
2101bdd6c0eSSue Gleeson 
2111bdd6c0eSSue Gleeson 	ASSERT(tgt != NULL);
2121bdd6c0eSSue Gleeson 	ASSERT(event != NULL);
2131bdd6c0eSSue Gleeson 
2141bdd6c0eSSue Gleeson 	ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
2151bdd6c0eSSue Gleeson 	ASSERT(ch != NULL);
2161bdd6c0eSSue Gleeson 
2171bdd6c0eSSue Gleeson 	SRPT_DPRINTF_L3("cm_conn_closed_hdlr, invoked for chan_hdl(%p),"
2181bdd6c0eSSue Gleeson 	    " event(%d)", (void *)ch->ch_chan_hdl,
2191bdd6c0eSSue Gleeson 	    event->cm_event.closed);
2201bdd6c0eSSue Gleeson 
2211bdd6c0eSSue Gleeson 	switch (event->cm_event.closed) {
2221bdd6c0eSSue Gleeson 
2231bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_DREP_RCVD:
2241bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_DREQ_TIMEOUT:
2251bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_DUP:
2261bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_ABORT:
2271bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_ALREADY:
2281bdd6c0eSSue Gleeson 		/*
2291bdd6c0eSSue Gleeson 		 * These cases indicate the SRP target initiated
2301bdd6c0eSSue Gleeson 		 * the closing of the channel and it is now closed.
2311bdd6c0eSSue Gleeson 		 * Cleanup the channel (which will remove the targets
2321bdd6c0eSSue Gleeson 		 * reference) and then release CM's reference.
2331bdd6c0eSSue Gleeson 		 */
2341bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_conn_closed_hdlr, local close call-back");
2351bdd6c0eSSue Gleeson 		srpt_ch_cleanup(ch);
2361bdd6c0eSSue Gleeson 		srpt_ch_release_ref(ch, 1);
2371bdd6c0eSSue Gleeson 		break;
2381bdd6c0eSSue Gleeson 
2391bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_DREQ_RCVD:
2401bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_REJ_RCVD:
2411bdd6c0eSSue Gleeson 	case IBT_CM_CLOSED_STALE:
2421bdd6c0eSSue Gleeson 		/*
2431bdd6c0eSSue Gleeson 		 * These cases indicate that the SRP initiator is closing
2441bdd6c0eSSue Gleeson 		 * the channel.  CM will have already closed the RC channel,
2451bdd6c0eSSue Gleeson 		 * so simply initiate cleanup which will remove the target
2461bdd6c0eSSue Gleeson 		 * ports reference to the channel and then release the
2471bdd6c0eSSue Gleeson 		 * reference held by the CM.
2481bdd6c0eSSue Gleeson 		 */
2491bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_conn_closed_hdlr, remote close,"
2501bdd6c0eSSue Gleeson 		    " free channel");
251*571d0d19SJohn Levon 		srpt_ch_cleanup(ch);
252*571d0d19SJohn Levon 		srpt_ch_release_ref(ch, 1);
2531bdd6c0eSSue Gleeson 		break;
2541bdd6c0eSSue Gleeson 
2551bdd6c0eSSue Gleeson 	default:
2561bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L2("cm_conn_closed_hdlr, unknown close type (%d)",
2571bdd6c0eSSue Gleeson 		    event->cm_event.closed);
2581bdd6c0eSSue Gleeson 		status = IBT_CM_DEFAULT;
2591bdd6c0eSSue Gleeson 		break;
2601bdd6c0eSSue Gleeson 	}
2611bdd6c0eSSue Gleeson 	return (status);
2621bdd6c0eSSue Gleeson }
2631bdd6c0eSSue Gleeson 
2641bdd6c0eSSue Gleeson /*
2651bdd6c0eSSue Gleeson  * srpt_cm_failure_hdlr() - Called when the channel is in error.  Cleanup
2661bdd6c0eSSue Gleeson  * and release the channel.
2671bdd6c0eSSue Gleeson  */
2681bdd6c0eSSue Gleeson static ibt_cm_status_t
srpt_cm_failure_hdlr(ibt_cm_event_t * event)2691bdd6c0eSSue Gleeson srpt_cm_failure_hdlr(ibt_cm_event_t *event)
2701bdd6c0eSSue Gleeson {
2711bdd6c0eSSue Gleeson 	srpt_channel_t		*ch;
2721bdd6c0eSSue Gleeson 
2731bdd6c0eSSue Gleeson 	ASSERT(event != NULL);
2741bdd6c0eSSue Gleeson 
2751bdd6c0eSSue Gleeson 	ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
2761bdd6c0eSSue Gleeson 	ASSERT(ch != NULL);
2771bdd6c0eSSue Gleeson 
2781bdd6c0eSSue Gleeson 	SRPT_DPRINTF_L3("cm_failure_hdlr, chan_hdl: 0x%p, code: %d"
2791bdd6c0eSSue Gleeson 	    "msg: %d reason: %d", (void *)event->cm_channel,
2801bdd6c0eSSue Gleeson 	    event->cm_event.failed.cf_code,
2811bdd6c0eSSue Gleeson 	    event->cm_event.failed.cf_msg,
2821bdd6c0eSSue Gleeson 	    event->cm_event.failed.cf_reason);
2831bdd6c0eSSue Gleeson 
2841bdd6c0eSSue Gleeson 	srpt_ch_cleanup(ch);
2851bdd6c0eSSue Gleeson 	srpt_ch_release_ref(ch, 1);
2861bdd6c0eSSue Gleeson 
2871bdd6c0eSSue Gleeson 	return (IBT_CM_ACCEPT);
2881bdd6c0eSSue Gleeson }
2891bdd6c0eSSue Gleeson 
2901bdd6c0eSSue Gleeson /*
2911bdd6c0eSSue Gleeson  * srpt_cm_hdlr() - CM call-back handler.
2921bdd6c0eSSue Gleeson  */
2931bdd6c0eSSue Gleeson ibt_cm_status_t
srpt_cm_hdlr(void * cm_private,ibt_cm_event_t * event,ibt_cm_return_args_t * ret_args,void * ret_priv_data,ibt_priv_data_len_t ret_len_max)2941bdd6c0eSSue Gleeson srpt_cm_hdlr(void *cm_private, ibt_cm_event_t *event,
295*571d0d19SJohn Levon     ibt_cm_return_args_t *ret_args, void *ret_priv_data,
296*571d0d19SJohn Levon     ibt_priv_data_len_t ret_len_max)
2971bdd6c0eSSue Gleeson {
2981bdd6c0eSSue Gleeson 	ibt_cm_status_t		status = IBT_CM_ACCEPT;
2991bdd6c0eSSue Gleeson 
3001bdd6c0eSSue Gleeson 	switch (event->cm_type) {
3011bdd6c0eSSue Gleeson 
3021bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_REQ_RCV:
3031bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, REQ received");
3041bdd6c0eSSue Gleeson 		status = srpt_cm_req_hdlr((srpt_target_port_t *)cm_private,
3051bdd6c0eSSue Gleeson 		    event, ret_args, ret_priv_data, ret_len_max);
3061bdd6c0eSSue Gleeson 		break;
3071bdd6c0eSSue Gleeson 
3081bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_REP_RCV:
3091bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, REP received");
3101bdd6c0eSSue Gleeson 		break;
3111bdd6c0eSSue Gleeson 
3121bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_MRA_RCV:
3131bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, MRA received");
3141bdd6c0eSSue Gleeson 		break;
3151bdd6c0eSSue Gleeson 
3161bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_CONN_EST:
3171bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, Connection established");
3181bdd6c0eSSue Gleeson 		status = srpt_cm_conn_est_hdlr(
3191bdd6c0eSSue Gleeson 		    (srpt_target_port_t *)cm_private, event);
3201bdd6c0eSSue Gleeson 		break;
3211bdd6c0eSSue Gleeson 
3221bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_CONN_CLOSED:
3231bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, Connection closed");
3241bdd6c0eSSue Gleeson 		status = srpt_cm_conn_closed_hdlr(
3251bdd6c0eSSue Gleeson 		    (srpt_target_port_t *)cm_private, event);
3261bdd6c0eSSue Gleeson 		break;
3271bdd6c0eSSue Gleeson 
3281bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_FAILURE:
3291bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, Event failure");
3301bdd6c0eSSue Gleeson 		status = srpt_cm_failure_hdlr(event);
3311bdd6c0eSSue Gleeson 		break;
3321bdd6c0eSSue Gleeson 
3331bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_LAP_RCV:
3341bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, LAP received");
3351bdd6c0eSSue Gleeson 		break;
3361bdd6c0eSSue Gleeson 
3371bdd6c0eSSue Gleeson 	case IBT_CM_EVENT_APR_RCV:
3381bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, APR received");
3391bdd6c0eSSue Gleeson 		break;
3401bdd6c0eSSue Gleeson 
3411bdd6c0eSSue Gleeson 	default:
3421bdd6c0eSSue Gleeson 		SRPT_DPRINTF_L3("cm_hdlr, unknown event received");
3431bdd6c0eSSue Gleeson 		break;
3441bdd6c0eSSue Gleeson 	}
3451bdd6c0eSSue Gleeson 
3461bdd6c0eSSue Gleeson 	return (status);
3471bdd6c0eSSue Gleeson }
348