30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * CDDL HEADER START
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * The contents of this file are subject to the terms of the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Common Development and Distribution License (the "License").
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * You may not use this file except in compliance with the License.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * or http://www.opensolaris.org/os/licensing.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * See the License for the specific language governing permissions
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and limitations under the License.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * When distributing Covered Code, include this CDDL HEADER in each
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * If applicable, add the following below this CDDL HEADER, with the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner]
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * CDDL HEADER END
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/ddi.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/sunddi.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/socket.h> /* networking stuff */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/sysmacros.h> /* offsetof */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/ib/clients/iser/iser.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/ib/clients/iser/iser_idm.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER transport routines
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * All transport functions except iser_tgt_svc_create() are called through
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the ops vector, iser_tgt_svc_create() is called from the async handler
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * inaddition to being called by the ULP
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_pdu_tx(idm_conn_t *ic, idm_pdu_t *pdu);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_buf_tx_to_ini(idm_task_t *idt, idm_buf_t *idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_buf_rx_from_ini(idm_task_t *idt, idm_buf_t *idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_tgt_enable_datamover(idm_conn_t *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_ini_enable_datamover(idm_conn_t *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_notice_key_values(struct idm_conn_s *ic,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *negotiated_nvl);
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Tingstatic kv_status_t iser_declare_key_values(struct idm_conn_s *ic,
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting nvlist_t *config_nvl, nvlist_t *outgoing_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_free_task_rsrcs(idm_task_t *idt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t iser_negotiate_key_values(idm_conn_t *ic,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t iser_handle_numerical(nvpair_t *nvp, uint64_t value,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap const idm_kv_xlate_t *ikvx, uint64_t min_value, uint64_t max_value,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_t iser_max_value, nvlist_t *request_nvl, nvlist_t *response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t iser_handle_boolean(nvpair_t *nvp, boolean_t value,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap const idm_kv_xlate_t *ikvx, boolean_t iser_value, nvlist_t *request_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *response_nvl, nvlist_t *negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t iser_handle_key(nvpair_t *nvp, const idm_kv_xlate_t *ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t iser_process_request_nvlist(nvlist_t *request_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *response_nvl, nvlist_t *negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic boolean_t iser_conn_is_capable(idm_conn_req_t *ic,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_transport_caps_t *caps);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_buf_alloc(idm_buf_t *idb, uint64_t buflen);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_buf_setup(idm_buf_t *idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_buf_teardown(idm_buf_t *idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_buf_free(idm_buf_t *idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_tgt_svc_destroy(struct idm_svc_s *is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_tgt_svc_online(struct idm_svc_s *is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_tgt_svc_offline(struct idm_svc_s *is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_tgt_conn_connect(struct idm_conn_s *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_ini_conn_create(idm_conn_req_t *cr,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap struct idm_conn_s *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_conn_destroy(struct idm_conn_s *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t iser_ini_conn_connect(struct idm_conn_s *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_conn_disconnect(struct idm_conn_s *ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER IDM transport operations
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapidm_transport_ops_t iser_transport_ops = {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_pdu_tx, /* it_tx_pdu */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_tx_to_ini, /* it_buf_tx_to_ini */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_rx_from_ini, /* it_buf_rx_from_ini */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_rx_datain */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_rx_rtt */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_rx_dataout */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_alloc_conn_rsrc */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_free_conn_rsrc */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_enable_datamover, /* it_tgt_enable_datamover */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_ini_enable_datamover, /* it_ini_enable_datamover */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL, /* it_conn_terminate */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_free_task_rsrcs, /* it_free_task_rsrc */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_negotiate_key_values, /* it_negotiate_key_values */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_notice_key_values, /* it_notice_key_values */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn_is_capable, /* it_conn_is_capable */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_alloc, /* it_buf_alloc */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_free, /* it_buf_free */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_setup, /* it_buf_setup */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_buf_teardown, /* it_buf_teardown */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_svc_create, /* it_tgt_svc_create */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_svc_destroy, /* it_tgt_svc_destroy */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_svc_online, /* it_tgt_svc_online */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_svc_offline, /* it_tgt_svc_offline */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn_destroy, /* it_tgt_conn_destroy */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_tgt_conn_connect, /* it_tgt_conn_connect */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn_disconnect, /* it_tgt_conn_disconnect */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_ini_conn_create, /* it_ini_conn_create */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn_destroy, /* it_ini_conn_destroy */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_ini_conn_connect, /* it_ini_conn_connect */
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting &iser_conn_disconnect, /* it_ini_conn_disconnect */
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting &iser_declare_key_values /* it_declare_key_values */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap};
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER IDM transport capabilities
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapidm_transport_caps_t iser_transport_caps = {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap 0 /* flags */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap};
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_idm_register()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_transport_attr_t attr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_status_t status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap attr.type = IDM_TRANSPORT_TYPE_ISER;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap attr.it_ops = &iser_transport_ops;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap attr.it_caps = &iser_transport_caps;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = idm_transport_register(&attr);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IDM_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "Failed to register iSER transport with IDM");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "Registered iSER transport with IDM");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ini_conn_create()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Allocate an iSER initiator connection context
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ini_conn_create(idm_conn_req_t *cr, idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan_t *iser_chan = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Allocate and set up a connection handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = kmem_zalloc(sizeof (iser_conn_t), KM_SLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_init(&iser_conn->ic_lock, NULL, MUTEX_DRIVER, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Allocate and open a channel to the target node */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan = iser_channel_alloc(NULL, &cr->cr_ini_dst_addr);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_chan == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "iser: failed to allocate channel");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(iser_conn, sizeof (iser_conn_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * The local IP and remote IP are filled in iser_channel_alloc. The
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * remote port needs to be filled in from idm_conn_req_t. The local
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * port is irrelevant. Internal representation of the port in the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IDM sockaddr structure is in network byte order. IBT expects the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * port in host byte order.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (cr->cr_ini_dst_addr.sin.sa_family) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan->ic_rport = ntohs(cr->cr_ini_dst_addr.sin4.sin_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET6:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan->ic_rport = ntohs(cr->cr_ini_dst_addr.sin6.sin6_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan->ic_rport = ISCSI_LISTEN_PORT;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan->ic_lport = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cv_init(&iser_conn->ic_stage_cv, NULL, CV_DEFAULT, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_type = ISER_CONN_TYPE_INI;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_ALLOCATED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_chan = iser_chan;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_idmc = ic;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Set a pointer to the iser_conn in the iser_chan for easy
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * access during CM event handling
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan->ic_conn = iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the iSER conn handle in the IDM conn private handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ic->ic_transport_private = (void *)iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the transport header length */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ic->ic_transport_hdrlen = ISER_HEADER_LENGTH;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_internal_conn_destroy()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Tear down iSER-specific connection resources. This is used below
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * in iser_conn_destroy(), but also from the CM code when we may have
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * some of the connection established, but not fully connected.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_internal_conn_destroy(iser_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&ic->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_channel_free(ic->ic_chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((ic->ic_type == ISER_CONN_TYPE_TGT) &&
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (ic->ic_stage == ISER_CONN_STAGE_ALLOCATED)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This is a target connection that has yet to be
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * established. Free our reference on the target
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * service handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_tgt_svc_rele(ic->ic_idms->is_iser_svc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cv_destroy(&ic->ic_stage_cv);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&ic->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&ic->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(ic, sizeof (iser_conn_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_conn_destroy()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Tear down an initiator or target connection.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_conn_destroy(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_internal_conn_destroy(iser_conn);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ic->ic_transport_private = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ini_conn_connect()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Establish the connection referred to by the handle previously allocated via
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ini_conn_create().
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ini_conn_connect(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status_t status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_channel_open(iser_conn->ic_chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "iser: failed to open channel");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Set the local and remote addresses in the idm conn handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_conv_ibtaddr2sockaddr(&ic->ic_laddr,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn->ic_chan->ic_localip, iser_conn->ic_chan->ic_lport);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_conv_ibtaddr2sockaddr(&ic->ic_raddr,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn->ic_chan->ic_remoteip, iser_conn->ic_chan->ic_rport);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Hold a reference on the IDM connection handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn_hold(ic);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_IC_CONNECTED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_conn_disconnect()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Shutdown this iSER connection
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_conn_disconnect(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_CLOSING;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Close the channel */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_channel_close(iser_conn->ic_chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free our reference held on the IDM conn handle, and set CLOSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn_rele(iser_conn->ic_idmc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_CLOSED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_svc_create()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Establish the CM service for inbound iSER service requests on the port
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * indicated by sr->sr_port.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * idm_svc_req_t contains the service parameters.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapidm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_create(idm_svc_req_t *sr, idm_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int rc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = kmem_zalloc(sizeof (iser_svc_t), KM_SLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is->is_iser_svc = (void *)iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_init(&iser_svc->is_refcnt, iser_svc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_create(&iser_svc->is_sbindlist, sizeof (iser_sbind_t),
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap offsetof(iser_sbind_t, is_list_node));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc->is_svcid = ibt_get_ip_sid(IPPROTO_TCP, sr->sr_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Register an iSER target service for the requested port
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and set the iser_svc structure in the idm_svc handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rc = iser_register_service(is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (rc != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_tgt_svc_create: iser_register_service "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failed on port (%d): rc (0x%x)", sr->sr_port, rc);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_release_ip_sid(iser_svc->is_svcid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_destroy(&iser_svc->is_sbindlist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_destroy(&iser_svc->is_refcnt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(iser_svc, sizeof (iser_svc_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* IDM refcnt utilities for the iSER service handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_hold(iser_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_hold(&is->is_refcnt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_rele(iser_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_rele(&is->is_refcnt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_svc_destroy()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Teardown resources allocated in iser_tgt_svc_create()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_destroy(idm_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = (iser_svc_t *)is->is_iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Deregister the iSER target service on this port and free
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the iser_svc structure from the idm_svc handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_deregister_service(is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Wait for the iSER service handle's refcnt to zero */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_wait_ref(&iser_svc->is_refcnt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_destroy(&iser_svc->is_sbindlist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_refcnt_destroy(&iser_svc->is_refcnt);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(iser_svc, sizeof (iser_svc_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_svc_online()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Bind the CM service allocated via iser_tgt_svc_create().
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_online(idm_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status_t status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&is->is_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Pass the IDM service handle as the client private data for
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * later use.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_bind_service(is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_tgt_svc_online: failed bind service");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&is->is_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&is->is_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_svc_offline
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Unbind the service on all available HCA ports.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_svc_offline(idm_svc_t *is)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&is->is_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_unbind_service(is);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&is->is_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_conn_connect()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Establish the connection in ic, passed from idm_tgt_conn_finish(), which
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * is invoked from the SM as a result of an inbound connection request.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_conn_connect(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* No action required */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_tgt_enable_datamover() sets the transport private data on the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * idm_conn_t and move the conn stage to indicate logged in.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_tgt_enable_datamover(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_LOGGED_IN;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ini_enable_datamover() is used by the iSCSI initator to request that a
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * specified iSCSI connection be transitioned to iSER-assisted mode.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * In the case of iSER, the RDMA resources for a reliable connection have
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * already been allocated at this time, and the 'RDMAExtensions' is set to 'Yes'
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * so no further negotiations are required at this time.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * The initiator now sends the first iSER Message - 'Hello' to the target
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and waits for the 'HelloReply' Message from the target before directing
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the initiator to go into the Full Feature Phase.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * No transport op is required on the target side.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ini_enable_datamover(idm_conn_t *ic)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap clock_t delay;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_HELLO_SENT;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Send the iSER Hello Message to the target */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_xfer_hello_msg(iser_conn->ic_chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_HELLO_SENT_FAIL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Acquire the iser_conn->ic_lock and wait for the iSER HelloReply
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Message from the target, i.e. iser_conn_stage_t to be set to
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * ISER_CONN_STAGE_HELLOREPLY_RCV. If the handshake does not
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * complete within a specified time period (.5s), then return failure.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap delay = ddi_get_lbolt() + drv_usectohz(500000);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap while ((iser_conn->ic_stage != ISER_CONN_STAGE_HELLOREPLY_RCV) &&
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (ddi_get_lbolt() < delay)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) cv_timedwait(&iser_conn->ic_stage_cv,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_conn->ic_lock, delay);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (iser_conn->ic_stage) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case ISER_CONN_STAGE_HELLOREPLY_RCV:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_LOGGED_IN;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Return suceess to indicate that the initiator connection can
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * go to the next phase - FFP
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_stage = ISER_CONN_STAGE_HELLOREPLY_RCV_FAIL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* STATEMENT_NEVER_REACHED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_free_task_rsrcs()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This routine does not currently need to do anything. It is used in
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the sockets transport to explicitly complete any buffers on the task,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * but we can rely on our RCaP layer to finish up it's work without any
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * intervention.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapidm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_free_task_rsrcs(idm_task_t *idt)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_negotiate_key_values() validates the key values for this connection
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_negotiate_key_values(idm_conn_t *ic, nvlist_t *request_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *response_nvl, nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kv_status_t kvrc = KV_HANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Process the request nvlist */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_process_request_nvlist(request_nvl, response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* We must be using RDMA, so set the flag on the ic handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ic->ic_rdma_extensions = B_TRUE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (kvrc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* Process a list of key=value pairs from a login request */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_process_request_nvlist(nvlist_t *request_nvl, nvlist_t *response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap const idm_kv_xlate_t *ikvx;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap char *nvp_name;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvpair_t *nvp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvpair_t *next_nvp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kv_status_t kvrc = KV_HANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap boolean_t transit = B_TRUE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Process the list */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvp = nvlist_next_nvpair(request_nvl, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap while (nvp != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap next_nvp = nvlist_next_nvpair(request_nvl, nvp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvp_name = nvpair_name(nvp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ikvx = idm_lookup_kv_xlate(nvp_name, strlen(nvp_name));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_key(nvp, ikvx, request_nvl, response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (kvrc != KV_HANDLED) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (kvrc == KV_HANDLED_NO_TRANSIT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* we countered, clear the transit flag */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap transit = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* error, bail out */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvp = next_nvp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * If the current kv_status_t indicates success, we've handled
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the entire list. Explicitly set kvrc to NO_TRANSIT if we've
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * cleared the transit flag along the way.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((kvrc == KV_HANDLED) && (transit == B_FALSE)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = KV_HANDLED_NO_TRANSIT;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (kvrc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* Handle a given list, boolean or numerical key=value pair */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_handle_key(nvpair_t *nvp, const idm_kv_xlate_t *ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kv_status_t kvrc = KV_UNHANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap boolean_t bool_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_t num_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int nvrc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Retrieve values for booleans and numericals */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (ikvx->ik_key_id) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Booleans */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_RDMA_EXTENSIONS:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_IMMEDIATE_DATA:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvpair_value_boolean_value(nvp, &bool_val);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Numericals */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_INITIATOR_RECV_DATA_SEGMENT_LENGTH:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_TARGET_RECV_DATA_SEGMENT_LENGTH:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_MAX_OUTSTANDING_UNEXPECTED_PDUS:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvpair_value_uint64(nvp, &num_val);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
2360e12de6667a0a73d68895549343137c26c892Peter Gill /*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Now handle the values according to the key name. Keys not
2360e12de6667a0a73d68895549343137c26c892Peter Gill * specifically handled here will be negotiated by the iscsi
2360e12de6667a0a73d68895549343137c26c892Peter Gill * target. Negotiated values take effect when
2360e12de6667a0a73d68895549343137c26c892Peter Gill * iser_notice_key_values gets called.
2360e12de6667a0a73d68895549343137c26c892Peter Gill */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (ikvx->ik_key_id) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_RDMA_EXTENSIONS:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure "Yes" */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_boolean(nvp, bool_val, ikvx, B_TRUE,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap request_nvl, response_nvl, negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_TARGET_RECV_DATA_SEGMENT_LENGTH:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Validate the proposed value */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_numerical(nvp, num_val, ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MIN,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_TARGET_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap request_nvl, response_nvl, negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_INITIATOR_RECV_DATA_SEGMENT_LENGTH:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Validate the proposed value */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_numerical(nvp, num_val, ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MIN,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_INITIATOR_RECV_DATA_SEGMENT_LENGTH_IMPL_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap request_nvl, response_nvl, negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_IMMEDIATE_DATA:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure "No" */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_boolean(nvp, bool_val, ikvx, B_FALSE,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap request_nvl, response_nvl, negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case KI_MAX_OUTSTANDING_UNEXPECTED_PDUS:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Validate the proposed value */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = iser_handle_numerical(nvp, num_val, ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MIN,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_MAX_OUTSTANDING_UNEXPECTED_PDUS_IMPL_MAX,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap request_nvl, response_nvl, negotiated_nvl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * All other keys, including invalid keys, will be
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * handled at the client layer.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = KV_HANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (kvrc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* Validate a proposed boolean value, and set the alternate if necessary */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_handle_boolean(nvpair_t *nvp, boolean_t value, const idm_kv_xlate_t *ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap boolean_t iser_value, nvlist_t *request_nvl, nvlist_t *response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill kv_status_t kvrc = KV_UNHANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int nvrc;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill boolean_t respond = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (value != iser_value) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Respond back to initiator with our value, and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * set the return value to unset the transit bit.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap value = iser_value;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill nvrc = nvlist_add_boolean_value(negotiated_nvl,
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill ikvx->ik_key_name, value);
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill if (nvrc == 0) {
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill kvrc = KV_HANDLED_NO_TRANSIT;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill respond = B_TRUE;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Add this to our negotiated values */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvlist_add_nvpair(negotiated_nvl, nvp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Respond if this is not a declarative */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap respond = (ikvx->ik_declarative == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Response of Simple-value Negotiation */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (nvrc == 0 && respond) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvlist_add_boolean_value(response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ikvx->ik_key_name, value);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Remove from the request (we've handled it) */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) nvlist_remove_all(request_nvl, ikvx->ik_key_name);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (kvrc == KV_HANDLED_NO_TRANSIT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (kvrc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (idm_nvstat_to_kvstat(nvrc));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Validate a proposed value against the iSER and/or iSCSI RFC's minimum and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * maximum values, and set an alternate, if necessary. Note that the value
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * 'iser_max_value" represents our implementation maximum (typically the max).
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic kv_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_handle_numerical(nvpair_t *nvp, uint64_t value, const idm_kv_xlate_t *ikvx,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_t min_value, uint64_t max_value, uint64_t iser_max_value,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill kv_status_t kvrc = KV_UNHANDLED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int nvrc;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill boolean_t respond = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Validate against standard */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((value < min_value) || (value > max_value)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kvrc = KV_VALUE_ERROR;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (value > iser_max_value) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Respond back to initiator with our value, and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * set the return value to unset the transit bit.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap value = iser_max_value;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill nvrc = nvlist_add_uint64(negotiated_nvl,
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill ikvx->ik_key_name, value);
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill if (nvrc == 0) {
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill kvrc = KV_HANDLED_NO_TRANSIT;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill respond = B_TRUE;
c050a449559fc53eab7574bb8f3d5f4bd85211f3Peter Gill }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Add this to our negotiated values */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvlist_add_nvpair(negotiated_nvl, nvp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Respond if this is not a declarative */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap respond = (ikvx->ik_declarative == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Response of Simple-value Negotiation */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (nvrc == 0 && respond) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nvrc = nvlist_add_uint64(response_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ikvx->ik_key_name, value);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Remove from the request (we've handled it) */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) nvlist_remove_all(request_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ikvx->ik_key_name);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (kvrc == KV_HANDLED_NO_TRANSIT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (kvrc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (idm_nvstat_to_kvstat(nvrc));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting/*
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting * iser_declare_key_values() declares the declarative key values for
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting * this connection.
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting */
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting/* ARGSUSED */
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Tingstatic kv_status_t
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Tingiser_declare_key_values(idm_conn_t *ic, nvlist_t *config_nvl,
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting nvlist_t *outgoing_nvl)
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting{
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting kv_status_t kvrc;
45680bd3312426f0b2a9e53e7b78a09c1fff0959Charles Ting int nvrc = 0;
45680bd3312426f0b2a9e53e7b78a09c1fff0959Charles Ting int rc;
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting uint64_t uint64_val;
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting
45680bd3312426f0b2a9e53e7b78a09c1fff0959Charles Ting if ((rc = nvlist_lookup_uint64(config_nvl,
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting ISER_KV_KEY_NAME_MAX_OUTSTANDING_PDU, &uint64_val)) != ENOENT) {
45680bd3312426f0b2a9e53e7b78a09c1fff0959Charles Ting ASSERT(rc == 0);
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting if (outgoing_nvl) {
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting nvrc = nvlist_add_uint64(outgoing_nvl,
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting ISER_KV_KEY_NAME_MAX_OUTSTANDING_PDU, uint64_val);
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting }
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting }
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting kvrc = idm_nvstat_to_kvstat(nvrc);
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting return (kvrc);
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting}
562610838fe0b8fdbe99a91a1dc13e77da2b6546Charles Ting
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_notice_key_values() activates the negotiated key values for
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * this connection.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_notice_key_values(idm_conn_t *ic, nvlist_t *negotiated_nvl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap boolean_t boolean_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_t uint64_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int nvrc;
2360e12de6667a0a73d68895549343137c26c892Peter Gill char *digest_choice_string;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Validate the final negotiated operational parameters,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and save a copy.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
2360e12de6667a0a73d68895549343137c26c892Peter Gill if ((nvrc = nvlist_lookup_string(negotiated_nvl,
2360e12de6667a0a73d68895549343137c26c892Peter Gill "HeaderDigest", &digest_choice_string)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
2360e12de6667a0a73d68895549343137c26c892Peter Gill
2360e12de6667a0a73d68895549343137c26c892Peter Gill /*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Per the iSER RFC, override the negotiated value with "None"
2360e12de6667a0a73d68895549343137c26c892Peter Gill */
2360e12de6667a0a73d68895549343137c26c892Peter Gill iser_conn->ic_op_params.op_header_digest = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
2360e12de6667a0a73d68895549343137c26c892Peter Gill if ((nvrc = nvlist_lookup_string(negotiated_nvl,
2360e12de6667a0a73d68895549343137c26c892Peter Gill "DataDigest", &digest_choice_string)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
2360e12de6667a0a73d68895549343137c26c892Peter Gill
2360e12de6667a0a73d68895549343137c26c892Peter Gill /*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Per the iSER RFC, override the negotiated value with "None"
2360e12de6667a0a73d68895549343137c26c892Peter Gill */
2360e12de6667a0a73d68895549343137c26c892Peter Gill iser_conn->ic_op_params.op_data_digest = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_boolean_value(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "RDMAExtensions", &boolean_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_op_params.op_rdma_extensions = boolean_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_boolean_value(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "OFMarker", &boolean_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
2360e12de6667a0a73d68895549343137c26c892Peter Gill /*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Per the iSER RFC, override the negotiated value with "No"
2360e12de6667a0a73d68895549343137c26c892Peter Gill */
2360e12de6667a0a73d68895549343137c26c892Peter Gill iser_conn->ic_op_params.op_ofmarker = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_boolean_value(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "IFMarker", &boolean_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
2360e12de6667a0a73d68895549343137c26c892Peter Gill /*
2360e12de6667a0a73d68895549343137c26c892Peter Gill * Per the iSER RFC, override the negotiated value with "No"
2360e12de6667a0a73d68895549343137c26c892Peter Gill */
2360e12de6667a0a73d68895549343137c26c892Peter Gill iser_conn->ic_op_params.op_ifmarker = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_uint64(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "TargetRecvDataSegmentLength", &uint64_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_op_params.op_target_recv_data_segment_length =
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_uint64(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "InitiatorRecvDataSegmentLength", &uint64_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_op_params.op_initiator_recv_data_segment_length =
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((nvrc = nvlist_lookup_uint64(negotiated_nvl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "MaxOutstandingUnexpectedPDUs", &uint64_val)) != ENOENT) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(nvrc == 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn->ic_op_params.op_max_outstanding_unexpected_pdus =
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint64_val;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Test boolean values which are required by RFC 5046 */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#ifdef ISER_DEBUG
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn->ic_op_params.op_rdma_extensions == B_TRUE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn->ic_op_params.op_header_digest == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn->ic_op_params.op_data_digest == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn->ic_op_params.op_ofmarker == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn->ic_op_params.op_ifmarker == B_FALSE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#endif
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_conn_is_capable() verifies that the passed connection is provided
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * for by an iSER-capable link.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * NOTE: When utilizing InfiniBand RC as an RCaP, this routine will check
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * if the link is on IPoIB. This only indicates a chance that the link is
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * on an RCaP, and thus iSER-capable, since we may be running on an IB-Eth
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * gateway, or other IB but non-RCaP link. Rather than fully establishing the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * link to verify RCaP here, we instead will return B_TRUE
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * indicating the link is iSER-capable, if the link is IPoIB. If then in
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ini_conn_create() the link proves not be RCaP, IDM will fall back
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * to using the IDM Sockets transport.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic boolean_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_conn_is_capable(idm_conn_req_t *cr, idm_transport_caps_t *caps)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* A NULL value for laddr indicates implicit source */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (iser_path_exists(NULL, &cr->cr_ini_dst_addr));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_pdu_tx() transmits a Control PDU via the iSER channel. We pull the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * channel out of the idm_conn_t passed in, and pass it and the pdu to the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_xfer routine.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_pdu_tx(idm_conn_t *ic, idm_pdu_t *pdu)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status_t iser_status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status = iser_xfer_ctrlpdu(iser_conn->ic_chan, pdu);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "iser_pdu_tx: failed iser_xfer_ctrlpdu: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "ic (0x%p) pdu (0x%p)", (void *) ic, (void *) pdu);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Fail this PDU transmission */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_pdu_complete(pdu, IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * We successfully posted this PDU for transmission.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * The completion handler will invoke idm_pdu_complete()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * with the completion status. See iser_cq.c for more
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * information.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_tx_to_ini() transmits the data buffer encoded in idb to the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * initiator to fulfill SCSI Read commands. An iser_xfer routine is invoked
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * to implement the RDMA operations.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Caller holds idt->idt_mutex.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_tx_to_ini(idm_task_t *idt, idm_buf_t *idb)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status_t iser_status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_status_t idm_status = IDM_STATUS_SUCCESS;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(mutex_owned(&idt->idt_mutex));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status = iser_xfer_buf_to_ini(idt, idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "iser_buf_tx_to_ini: failed "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "iser_xfer_buf_to_ini: idt (0x%p) idb (0x%p)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void *) idt, (void *) idb);
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan idm_buf_tx_to_ini_done(idt, idb, IDM_STATUS_ABORTED);
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSCSIt's Data Completion Notify callback is invoked from
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the Work Request Send completion Handler
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&idt->idt_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (idm_status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_tx_from_ini() transmits data from the initiator into the buffer
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * in idb to fulfill SCSI Write commands. An iser_xfer routine is invoked
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * to implement the RDMA operations.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Caller holds idt->idt_mutex.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_rx_from_ini(idm_task_t *idt, idm_buf_t *idb)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status_t iser_status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_status_t idm_status = IDM_STATUS_SUCCESS;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(mutex_owned(&idt->idt_mutex));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_status = iser_xfer_buf_from_ini(idt, idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_status != ISER_STATUS_SUCCESS) {
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan ISER_LOG(CE_WARN, "iser_buf_rx_from_ini: failed "
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan "iser_xfer_buf_from_ini: idt (0x%p) idb (0x%p)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void *) idt, (void *) idb);
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan idm_buf_rx_from_ini_done(idt, idb, IDM_STATUS_ABORTED);
6fd984eca41d3425a2dc1f01db27c96a33046265Priya Krishnan return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSCSIt's Data Completion Notify callback is invoked from
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the Work Request Send completion Handler
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&idt->idt_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (idm_status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_alloc() allocates a buffer and registers it with the IBTF for
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * use with iSER. Each HCA has it's own kmem cache for establishing a pool
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * of registered buffers, when once initially allocated, will remain
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * registered with the HCA. This routine is invoked only on the target,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * where we have the requirement to pre-allocate buffers for the upper layers.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Note: buflen is compared to ISER_DEFAULT_BUFLEN, and allocation is failed
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * if the requested buflen is larger than our default.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_alloc(idm_buf_t *idb, uint64_t buflen)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *iser_hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf_t *iser_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (buflen > ISER_DEFAULT_BUFLEN) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)idb->idb_ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca = iser_conn->ic_chan->ic_hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Allocate a buffer from this HCA's cache. Once initialized, these
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * will remain allocated and registered (see above).
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf = kmem_cache_alloc(iser_hca->iser_buf_cache, KM_NOSLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_buf == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_buf_alloc: alloc failed");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the allocated data buffer pointer in the IDM buf handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_buf = iser_buf->buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the private buf and reg handles in the IDM buf handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_buf_private = (void *)iser_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_reg_private = (void *)iser_buf->iser_mr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_free() frees the buffer handle passed in. Note that the cached
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * kmem object has an HCA-registered buffer in it which will not be freed.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This allows us to build up a cache of pre-allocated and registered
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * buffers for use on the target.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_free(idm_buf_t *buf)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf_t *iser_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf = buf->idb_buf_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_cache_free(iser_buf->cache, iser_buf);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_setup() is invoked on the initiator in order to register memory
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * on demand for use with the iSER layer.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic idm_status_t
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_setup(idm_buf_t *idb)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan_t *iser_chan;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *iser_hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf_t *iser_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(idb->idb_buf != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)idb->idb_ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_conn != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca = iser_conn->ic_chan->ic_hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan = iser_conn->ic_chan;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(iser_chan != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Memory registration is known to be slow, so for small
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * transfers, use pre-registered memory buffers and just
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * copy the data into/from them at the appropriate time
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idb->idb_buflen < ISER_BCOPY_THRESHOLD) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_buf =
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_cache_alloc(iser_hca->iser_buf_cache, KM_NOSLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_buf == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Fail over to dynamic registration */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_reg_rdma_mem(iser_chan->ic_hca, idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_bufalloc = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Set the allocated data buffer pointer in the IDM buf handle
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Data is to be copied from/to this buffer using bcopy
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_bufptr = idb->idb_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_bufbcopy = B_TRUE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_buf = iser_buf->buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the private buf and reg handles in the IDM buf handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_buf_private = (void *)iser_buf;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_reg_private = (void *)iser_buf->iser_mr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure bufalloc'd flag is set */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_bufalloc = B_TRUE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Dynamically register the memory passed in on the idb */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_reg_rdma_mem(iser_chan->ic_hca, idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure bufalloc'd flag is unset */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idb->idb_bufalloc = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_buf_teardown() is invoked on the initiator in order to register memory
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * on demand for use with the iSER layer.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_buf_teardown(idm_buf_t *idb)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = (iser_conn_t *)idb->idb_ic->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Deregister the memory passed in on the idb */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_dereg_rdma_mem(iser_conn->ic_chan->ic_hca, idb);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}