1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CDDL HEADER START
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * The contents of this file are subject to the terms of the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Common Development and Distribution License (the "License").
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * You may not use this file except in compliance with the License.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * or http://www.opensolaris.org/os/licensing.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * See the License for the specific language governing permissions
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * and limitations under the License.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * When distributing Covered Code, include this CDDL HEADER in each
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If applicable, add the following below this CDDL HEADER, with the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * fields enclosed by brackets "[]" replaced with your own identifying
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * information: Portions Copyright [yyyy] [name of copyright owner]
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CDDL HEADER END
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * IB CM handlers for s Solaris SCSI RDMA Protocol Target (SRP)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * transport port provider module for the COMSTAR framework.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/cpuvar.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/types.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/conf.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/stat.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/file.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sunddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/modctl.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sysmacros.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sdt.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/taskq.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ib/ibtl/ibti.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf_ioctl.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/portif.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_impl.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_cm.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_stp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_ch.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonextern uint16_t srpt_send_msg_depth;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonextern srpt_ctxt_t *srpt_ctxt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_cm_req_hdlr() - Login request
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CM has called back with a CM REQ message associated with an
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SRP initiator login request.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic ibt_cm_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_cm_req_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_return_args_t *ret_args, void *ret_priv_data,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_priv_data_len_t ret_priv_data_len)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_req_rcv_t *req;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_req_t login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_rej_t login_rej;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_rsp_t login_rsp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch = NULL;
191c289b86668766245f78ec1f87557319bc46a1Charles Ting char remote_gid[SRPT_ALIAS_LEN];
191c289b86668766245f78ec1f87557319bc46a1Charles Ting char local_gid[SRPT_ALIAS_LEN];
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req = &event->cm_event.req;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (event->cm_priv_data_len < sizeof (srp_login_req_t)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_req_hdlr, IU size expected (>= %d),"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " received size (%d)", (uint_t)sizeof (srp_login_req_t),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_priv_data_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_REJECT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (event->cm_priv_data == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP private data pointer");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_REJECT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ret_priv_data_len < sizeof (srp_login_rej_t)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_req_hdlr, return private len too"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " small (%d)", ret_priv_data_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_REJECT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ret_priv_data == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP return private data"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " pointer");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_REJECT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Copy to avoid potential alignment problems, process login
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * creating a new channel and possibly session.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(event->cm_priv_data, &login, sizeof (login));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(local_gid,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting req->req_prim_addr.av_sgid.gid_prefix,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting req->req_prim_addr.av_sgid.gid_guid);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(remote_gid,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting req->req_prim_addr.av_dgid.gid_prefix,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting req->req_prim_addr.av_dgid.gid_guid);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = srpt_stp_login(tgt, &login, &login_rsp,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting &login_rej, req->req_prim_hca_port, local_gid, remote_gid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(&login_rsp, ret_priv_data, SRP_LOGIN_RSP_SIZE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret_len = SRP_LOGIN_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_req_hdlr, rsp priv len(%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " ch created on port(%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", cm_req_hdlr, req ra_out(%d), ra_in(%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", retry(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret_len, req->req_prim_hca_port,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req->req_rdma_ra_out, req->req_rdma_ra_in,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req->req_retry_cnt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_channel = ch->ch_chan_hdl;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rdma_ra_out =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson min(tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req->req_rdma_ra_in);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rdma_ra_in =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson min(tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req->req_rdma_ra_out);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rnr_retry_cnt = req->req_retry_cnt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_req_hdlr, hca_max_rdma_in_chan (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", hca_max_rdma_out_chan (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", updated ra_out(%d), ra_in(%d), retry(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rdma_ra_out,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rdma_ra_in,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret.rep.cm_rnr_retry_cnt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = IBT_CM_ACCEPT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(&login_rej, ret_priv_data, sizeof (login_rej));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ret_args->cm_ret_len = sizeof (login_rej);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = IBT_CM_REJECT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_cm_conn_est_hdlr() - Connection established
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CM has called back to inform us that a connection attempt has
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * completed (explicit or implicit) and may now be used.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic ibt_cm_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_cm_conn_est_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(event != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_conn_est_hdlr, invoked for ch(%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&ch->ch_rwlock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_state != SRPT_CHANNEL_CONNECTED) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_conn_est_hdlr, invalid ch state (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_state);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_REJECT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_state = SRPT_CHANNEL_CONNECTED;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_ACCEPT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_cm_conn_closed_hdlr() - Channel closed
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CM callback indicating a channel has been completely closed.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic ibt_cm_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_cm_conn_closed_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_status_t status = IBT_CM_ACCEPT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(event != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_conn_closed_hdlr, invoked for chan_hdl(%p),"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " event(%d)", (void *)ch->ch_chan_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_event.closed);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson switch (event->cm_event.closed) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_DREP_RCVD:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_DREQ_TIMEOUT:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_DUP:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_ABORT:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_ALREADY:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * These cases indicate the SRP target initiated
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the closing of the channel and it is now closed.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Cleanup the channel (which will remove the targets
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * reference) and then release CM's reference.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_conn_closed_hdlr, local close call-back");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_cleanup(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_release_ref(ch, 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_DREQ_RCVD:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_REJ_RCVD:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_CLOSED_STALE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * These cases indicate that the SRP initiator is closing
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the channel. CM will have already closed the RC channel,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * so simply initiate cleanup which will remove the target
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * ports reference to the channel and then release the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * reference held by the CM.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_conn_closed_hdlr, remote close,"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " free channel");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_cleanup(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_release_ref(ch, 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_conn_closed_hdlr, NULL channel");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson default:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("cm_conn_closed_hdlr, unknown close type (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_event.closed);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = IBT_CM_DEFAULT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_cm_failure_hdlr() - Called when the channel is in error. Cleanup
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * and release the channel.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic ibt_cm_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_cm_failure_hdlr(ibt_cm_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(event != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_failure_hdlr, chan_hdl: 0x%p, code: %d"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "msg: %d reason: %d", (void *)event->cm_channel,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_event.failed.cf_code,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_event.failed.cf_msg,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->cm_event.failed.cf_reason);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_cleanup(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_release_ref(ch, 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_CM_ACCEPT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_cm_hdlr() - CM call-back handler.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonibt_cm_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_cm_hdlr(void *cm_private, ibt_cm_event_t *event,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_return_args_t *ret_args, void *ret_priv_data,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_priv_data_len_t ret_len_max)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_cm_status_t status = IBT_CM_ACCEPT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson switch (event->cm_type) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_REQ_RCV:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, REQ received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_cm_req_hdlr((srpt_target_port_t *)cm_private,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event, ret_args, ret_priv_data, ret_len_max);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_REP_RCV:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, REP received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_MRA_RCV:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, MRA received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_CONN_EST:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, Connection established");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_cm_conn_est_hdlr(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (srpt_target_port_t *)cm_private, event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_CONN_CLOSED:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, Connection closed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_cm_conn_closed_hdlr(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (srpt_target_port_t *)cm_private, event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_FAILURE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, Event failure");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_cm_failure_hdlr(event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_LAP_RCV:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, LAP received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_CM_EVENT_APR_RCV:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, APR received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson default:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("cm_hdlr, unknown event received");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}