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/types.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/ddi.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/types.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/socket.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <netinet/in.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/sunddi.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/sysmacros.h>
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap#include <sys/iscsi_protocol.h>
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_ib.c
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Routines for InfiniBand transport for iSER
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This file contains the routines to interface with the IBT API to attach and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * allocate IB resources, handle async events, and post recv work requests.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_hca_t *iser_ib_gid2hca(ib_gid_t gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_hca_t *iser_ib_guid2hca(ib_guid_t guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_hca_t *iser_ib_alloc_hca(ib_guid_t guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_free_hca(iser_hca_t *hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_update_hcaports(iser_hca_t *hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_init_hcas(void);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_fini_hcas(void);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_sbind_t *iser_ib_get_bind(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc, ib_guid_t hca_guid, ib_gid_t gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_activate_port(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc_t *idm_svc, ib_guid_t guid, ib_gid_t gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_deactivate_port(ib_guid_t hca_guid, ib_gid_t gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_init_qp(iser_chan_t *chan, uint_t sq_size, uint_t rq_size);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_fini_qp(iser_qp_t *qp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int iser_ib_setup_cq(ibt_hca_hdl_t hca_hdl, uint_t cq_size,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_cq_hdl_t *cq_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_setup_chanargs(uint8_t hca_port, ibt_cq_hdl_t scq_hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_cq_hdl_t rcq_hdl, uint_t sq_size, uint_t rq_size,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_pd_hdl_t hca_pdhdl, ibt_rc_chan_alloc_args_t *cargs);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_handle_portup_event(ibt_hca_hdl_t hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_async_event_t *event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_handle_portdown_event(ibt_hca_hdl_t hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_async_event_t *event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void iser_ib_handle_hca_detach_event(ibt_hca_hdl_t hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_async_event_t *event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapstatic void iser_ib_post_recv_task(void *arg);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic struct ibt_clnt_modinfo_s iser_ib_modinfo = {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap IBTI_V_CURR,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap IBT_STORAGE_DEV,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_async_handler,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap NULL,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "iSER"
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap};
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_init
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function registers the HCA drivers with IBTF and registers and binds
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER as a service with IBTF.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_init(void)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Register with IBTF */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_attach(&iser_ib_modinfo, iser_state->is_dip, iser_state,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &iser_state->is_ibhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_init: ibt_attach failed (0x%x)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Create the global work request kmem_cache */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->iser_wr_cache = kmem_cache_create("iser_wr_cache",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sizeof (iser_wr_t), 0, NULL, NULL, NULL,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state, NULL, KM_SLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Populate our list of HCAs */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_init_hcas();
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* HCAs failed to initialize, tear it down */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_cache_destroy(iser_state->iser_wr_cache);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_detach(iser_state->is_ibhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_ibhdl = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_init: failed to initialize HCAs");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Target will register iSER as a service with IBTF when required */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Target will bind this service when it comes online */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_fini
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function unbinds and degisters the iSER service from IBTF
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_fini(void)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* IDM would have already disabled all the services */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Teardown the HCA list and associated resources */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_ib_fini_hcas() != DDI_SUCCESS)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Teardown the global work request kmem_cache */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_cache_destroy(iser_state->iser_wr_cache);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Deregister with IBTF */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_state->is_ibhdl != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_detach(iser_state->is_ibhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_ibhdl = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_register_service
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function registers the iSER service using the RDMA-Aware Service ID.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_register_service(idm_svc_t *idm_svc)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_srv_desc_t srvdesc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bzero(&srvdesc, sizeof (ibt_srv_desc_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set up IBTI client callback handler from the CM */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap srvdesc.sd_handler = iser_ib_cm_handler;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap srvdesc.sd_flags = IBT_SRV_NO_FLAGS;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = (iser_svc_t *)idm_svc->is_iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Register the service on the specified port */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_register_service(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_ibhdl, &srvdesc,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc->is_svcid, 1, &iser_svc->is_srvhdl, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_bind_service
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * This function binds a given iSER service on all available HCA ports. The
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * current specification does not allow user to specify transport bindings
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * for each iscsi target. The ULP invokes this function to bind the target
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * to all available iser ports after checking for the presence of an IB HCA.
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * iSER is "configured" whenever an IB-capable IP address exists. The lack
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * of active IB ports is a less-fatal condition, and sockets would be used
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * as the transport even though an Infiniband HCA is configured but unusable.
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_bind_service(idm_svc_t *idm_svc)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ib_gid_t gid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int num_ports = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int num_binds = 0;
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan int num_inactive_binds = 0; /* if HCA ports inactive */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int i;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(idm_svc != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(idm_svc->is_iser_svc != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Register the iSER service on all available ports */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (hca = list_head(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = list_next(&iser_state->is_hcalist, hca)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (i = 0; i < hca->hca_num_ports; i++) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap num_ports++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_port_info[i].p_linkstate !=
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap IBT_PORT_ACTIVE) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Move on. We will attempt to bind service
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * in our async handler if the port comes up
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * at a later time.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan num_inactive_binds++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap gid = hca->hca_port_info[i].p_sgid_tbl[0];
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* If the port is already bound, skip */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_ib_get_bind(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc->is_iser_svc, hca->hca_guid, gid) == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_activate_port(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc, hca->hca_guid, gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "iser_ib_bind_service: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "iser_ib_activate_port failure "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "(0x%x)", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap num_binds++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (num_binds) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_bind_service: Service available on "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "(%d) of (%d) ports", num_binds, num_ports);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (ISER_STATUS_SUCCESS);
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan } else if (num_inactive_binds) {
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_bind_service: Could not bind "
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan "service, HCA ports are not active.");
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan /*
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * still considered success, the async handler will bind
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan * the service when the port comes up at a later time
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan */
32c66a4da4528e641a7f3b223c32df190340fe1cPriya Krishnan return (ISER_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_bind_service: Did not bind service");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (ISER_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_unbind_service
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function unbinds a given service on a all HCA ports
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_unbind_service(idm_svc_t *idm_svc)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_sbind_t *is_sbind, *next_sb;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idm_svc != NULL && idm_svc->is_iser_svc != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = idm_svc->is_iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (is_sbind = list_head(&iser_svc->is_sbindlist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind = next_sb) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap next_sb = list_next(&iser_svc->is_sbindlist, is_sbind);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_unbind_service(iser_svc->is_srvhdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind->is_sbindhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_remove(&iser_svc->is_sbindlist, is_sbind);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(is_sbind, sizeof (iser_sbind_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_deregister_service(idm_svc_t *idm_svc)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idm_svc != NULL && idm_svc->is_iser_svc != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = (iser_svc_t *)idm_svc->is_iser_svc;
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_deregister_service(iser_state->is_ibhdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc->is_srvhdl);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_release_ip_sid(iser_svc->is_svcid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_get_paths
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function finds the IB path between the local and the remote address.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_get_paths(ibt_ip_addr_t *local_ip, ibt_ip_addr_t *remote_ip,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_path_info_t *path, ibt_path_ip_src_t *path_src_ip)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_ip_path_attr_t ipattr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) bzero(&ipattr, sizeof (ibt_ip_path_attr_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipattr.ipa_dst_ip = remote_ip;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipattr.ipa_src_ip = *local_ip;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipattr.ipa_max_paths = 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipattr.ipa_ndst = 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) bzero(path, sizeof (ibt_path_info_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_get_ip_paths(iser_state->is_ibhdl, IBT_PATH_NO_FLAGS,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &ipattr, path, NULL, path_src_ip);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "ibt_get_ip_paths: ibt_get_ip_paths "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failure: status (%d)", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (local_ip != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_get_paths success: IP[%x to %x]",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap local_ip->un.ip4addr, remote_ip->un.ip4addr);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_get_paths success: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "IP[INADDR_ANY to %x]", remote_ip->un.ip4addr);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (ISER_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * iser_ib_alloc_channel_nopathlookup
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * This function allocates a reliable connected channel. This function does
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * not invoke ibt_get_ip_paths() to do the path lookup. The HCA GUID and
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * port are input to this function.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_chan_t *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnaniser_ib_alloc_channel_nopathlookup(ib_guid_t hca_guid, uint8_t hca_port)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan iser_hca_t *hca;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan iser_chan_t *chan;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan /* Lookup the hca using the gid in the path info */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan hca = iser_ib_guid2hca(hca_guid);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan if (hca == NULL) {
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_nopathlookup: failed "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "to lookup HCA(%llx) handle", (longlong_t)hca_guid);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan return (NULL);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan chan = iser_ib_alloc_rc_channel(hca, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan if (chan == NULL) {
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_nopathlookup: failed "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "to alloc channel on HCA(%llx) %d",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)hca_guid, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan return (NULL);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_pathlookup success: "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "chanhdl (0x%p), HCA(%llx) %d",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (void *)chan->ic_chanhdl, (longlong_t)hca_guid, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan return (chan);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan}
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan/*
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * iser_ib_alloc_channel_pathlookup
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * This function allocates a reliable connected channel but first invokes
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * ibt_get_ip_paths() with the given local and remote addres to get the
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * HCA lgid and the port number.
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnaniser_chan_t *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnaniser_ib_alloc_channel_pathlookup(
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ibt_ip_addr_t *local_ip, ibt_ip_addr_t *remote_ip)
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan{
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ibt_path_info_t ibt_path;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ibt_path_ip_src_t path_src_ip;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ib_gid_t lgid;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan uint8_t hca_port; /* from path */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan iser_hca_t *hca;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan iser_chan_t *chan;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Lookup a path to the given destination */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan status = iser_ib_get_paths(
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan local_ip, remote_ip, &ibt_path, &path_src_ip);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_pathlookup: faild "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "Path lookup IP:[%llx to %llx] failed: status (%d)",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)local_ip->un.ip4addr,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)remote_ip->un.ip4addr,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* get the local gid from the path info */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan lgid = ibt_path.pi_prim_cep_path.cep_adds_vect.av_sgid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* get the hca port from the path info */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan hca_port = ibt_path.pi_prim_cep_path.cep_hca_port_num;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Lookup the hca using the gid in the path info */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_gid2hca(lgid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca == NULL) {
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_pathlookup: failed "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "to lookup HCA (%llx) handle",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)hca->hca_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan chan = iser_ib_alloc_rc_channel(hca, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan if (chan == NULL) {
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_pathlookup: failed "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "to alloc channel from IP:[%llx to %llx] on HCA (%llx) %d",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)local_ip->un.ip4addr,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)remote_ip->un.ip4addr,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)hca->hca_guid, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan return (NULL);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan }
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ISER_LOG(CE_NOTE, "iser_ib_alloc_channel_pathlookup success: "
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan "chanhdl (0x%p), IP:[%llx to %llx], lgid (%llx:%llx), HCA(%llx) %d",
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (void *)chan->ic_chanhdl,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)local_ip->un.ip4addr,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)remote_ip->un.ip4addr,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)lgid.gid_prefix, (longlong_t)lgid.gid_guid,
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan (longlong_t)hca->hca_guid, hca_port);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan chan->ic_ibt_path = ibt_path;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_localip = path_src_ip.ip_primary;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_remoteip = *remote_ip;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan return (chan);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan}
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan/*
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * iser_ib_alloc_rc_channel
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * This function allocates a reliable communication channel using the specified
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan * channel attributes.
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnaniser_chan_t *
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnaniser_ib_alloc_rc_channel(iser_hca_t *hca, uint8_t hca_port)
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan{
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan iser_chan_t *chan;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan ibt_rc_chan_alloc_args_t chanargs;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan uint_t sq_size, rq_size;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan int status;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan chan = kmem_zalloc(sizeof (iser_chan_t), KM_SLEEP);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_init(&chan->ic_chan_lock, NULL, MUTEX_DRIVER, NULL);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan mutex_init(&chan->ic_sq_post_lock, NULL, MUTEX_DRIVER, NULL);
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan /* Set up the iSER channel handle with HCA */
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan chan->ic_hca = hca;
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Determine the queue sizes, based upon the HCA query data.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * For our Work Queues, we will use either our default value,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * or the HCA's maximum value, whichever is smaller.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sq_size = min(hca->hca_attr.hca_max_chan_sz, ISER_IB_SENDQ_SIZE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rq_size = min(hca->hca_attr.hca_max_chan_sz, ISER_IB_RECVQ_SIZE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * For our Completion Queues, we again check the device maximum.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * We want to end up with CQs that are the next size up from the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * WQs they are servicing so that they have some overhead.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_attr.hca_max_cq_sz >= (sq_size + 1)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_sendcq_sz = sq_size + 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_sendcq_sz = hca->hca_attr.hca_max_cq_sz;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sq_size = chan->ic_sendcq_sz - 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_attr.hca_max_cq_sz >= (rq_size + 1)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_recvcq_sz = rq_size + 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_recvcq_sz = hca->hca_attr.hca_max_cq_sz;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rq_size = chan->ic_recvcq_sz - 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the iSER channel's QP handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_init_qp(chan, sq_size, rq_size);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set up the Send Completion Queue */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_setup_cq(hca->hca_hdl, chan->ic_sendcq_sz,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &chan->ic_sendcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_fini_qp(&chan->ic_qp);
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&chan->ic_sq_post_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(chan, sizeof (iser_chan_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_set_cq_handler(chan->ic_sendcq, iser_ib_sendcq_handler, chan);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_enable_cq_notify(chan->ic_sendcq, IBT_NEXT_COMPLETION);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set up the Receive Completion Queue */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_setup_cq(hca->hca_hdl, chan->ic_recvcq_sz,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &chan->ic_recvcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != ISER_STATUS_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_cq(chan->ic_sendcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_fini_qp(&chan->ic_qp);
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&chan->ic_sq_post_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(chan, sizeof (iser_chan_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_set_cq_handler(chan->ic_recvcq, iser_ib_recvcq_handler, chan);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_enable_cq_notify(chan->ic_recvcq, IBT_NEXT_COMPLETION);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Setup the channel arguments */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_setup_chanargs(hca_port, chan->ic_sendcq, chan->ic_recvcq,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sq_size, rq_size, hca->hca_pdhdl, &chanargs);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_alloc_rc_channel(hca->hca_hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap IBT_ACHAN_NO_FLAGS, &chanargs, &chan->ic_chanhdl, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_alloc_rc_channel: failed "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "ibt_alloc_rc_channel: status (%d)", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_cq(chan->ic_sendcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_cq(chan->ic_recvcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_fini_qp(&chan->ic_qp);
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&chan->ic_sq_post_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(chan, sizeof (iser_chan_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the 'channel' as the client private data */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_set_chan_private(chan->ic_chanhdl, chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (chan);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_open_rc_channel
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function opens a RC connection on the given allocated RC channel
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapint
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_open_rc_channel(iser_chan_t *chan)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_ip_cm_info_t ipcm_info;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_private_data_t iser_priv_data;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_chan_open_args_t ocargs;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_rc_returns_t ocreturns;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * For connection establishment, the initiator sends a CM REQ using the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER RDMA-Aware Service ID. Included are the source and destination
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IP addresses, and the src port.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bzero(&ipcm_info, sizeof (ibt_ip_cm_info_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipcm_info.src_addr = chan->ic_localip;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipcm_info.dst_addr = chan->ic_remoteip;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ipcm_info.src_port = chan->ic_lport;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * The CM Private Data field defines the iSER connection parameters
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * such as zero based virtual address exception (ZBVAE) and Send with
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * invalidate Exception (SIE).
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Solaris IBT does not currently support ZBVAE or SIE.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_priv_data.rsvd1 = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_priv_data.sie = 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_priv_data.zbvae = 1;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_format_ip_private_data(&ipcm_info,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sizeof (iser_private_data_t), &iser_priv_data);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_open_rc_channel failed: %d", status);
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Set the SID we are attempting to connect to, based upon the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * remote port number.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_ibt_path.pi_sid = ibt_get_ip_sid(IPPROTO_TCP, chan->ic_rport);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set up the args for the channel open */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bzero(&ocargs, sizeof (ibt_chan_open_args_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_path = &chan->ic_ibt_path;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_cm_handler = iser_ib_cm_handler;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_cm_clnt_private = iser_state;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_rdma_ra_out = 4;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_rdma_ra_in = 4;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_path_retry_cnt = 2;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_path_rnr_retry_cnt = 2;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_priv_data_len = sizeof (iser_private_data_t);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ocargs.oc_priv_data = &iser_priv_data;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bzero(&ocreturns, sizeof (ibt_rc_returns_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_open_rc_channel(chan->ic_chanhdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap IBT_OCHAN_NO_FLAGS, IBT_BLOCKING, &ocargs, &ocreturns);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_open_rc_channel failed: %d", status);
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IDM_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_close_rc_channel
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function closes the RC channel related to this iser_chan handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * We invoke this in a non-blocking, no callbacks context.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_close_rc_channel(iser_chan_t *chan)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_enter(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_close_rc_channel(chan->ic_chanhdl, IBT_BLOCKING, NULL,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap 0, NULL, NULL, 0);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_close_rc_channel: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "ibt_close_rc_channel failed: status (%d)", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_exit(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_free_rc_channel
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function tears down an RC channel's QP initialization and frees it.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Note that we do not need synchronization here; the channel has been
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * closed already, so we should only have completion polling occuring. Once
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * complete, we are free to free the IBTF channel, WQ and CQ resources, and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * our own related resources.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_free_rc_channel(iser_chan_t *chan)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp_t *iser_qp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp = &chan->ic_qp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure the SQ is empty */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap while (chan->ic_sq_post_count != 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap delay(drv_usectohz(ISER_DELAY_HALF_SECOND));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&chan->ic_sq_post_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Ensure the RQ is empty */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_flush_channel(chan->ic_chanhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap while (iser_qp->rq_level != 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap delay(drv_usectohz(ISER_DELAY_HALF_SECOND));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free our QP handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) iser_ib_fini_qp(iser_qp);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free the IBT channel resources */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_channel(chan->ic_chanhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_chanhdl = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free the CQs */
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_free_cq(chan->ic_sendcq);
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_free_cq(chan->ic_recvcq);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free the chan handle */
92adbba74606fdfb5f11be2a6497e53ff2224507Peter Cudhea - Sun Microsystems - Burlington, MA United States mutex_destroy(&chan->ic_chan_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(chan, sizeof (iser_chan_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_post_recv
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function handles keeping the RQ full on a given channel.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This routine will mostly be run on a taskq, and will check the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * current fill level of the RQ, and post as many WRs as necessary
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * to fill it again.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapint
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapiser_ib_post_recv_async(ibt_channel_hdl_t chanhdl)
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap{
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap iser_chan_t *chan;
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap int status;
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap /* Pull our iSER channel handle from the private data */
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap chan = (iser_chan_t *)ibt_get_chan_private(chanhdl);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap /*
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap * Caller must check that chan->ic_conn->ic_stage indicates
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap * the connection is active (not closing, not closed) and
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap * it must hold the mutex cross the check and the call to this function
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap */
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap ASSERT(mutex_owned(&chan->ic_conn->ic_lock));
2360e12de6667a0a73d68895549343137c26c892Peter Gill ASSERT((chan->ic_conn->ic_stage >= ISER_CONN_STAGE_ALLOCATED) &&
72cf314316bed51cd2e5fd0cb021a9725316a6b0peter dunlap (chan->ic_conn->ic_stage <= ISER_CONN_STAGE_LOGGED_IN));
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap idm_conn_hold(chan->ic_conn->ic_idmc);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap status = ddi_taskq_dispatch(iser_taskq, iser_ib_post_recv_task,
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap (void *)chanhdl, DDI_NOSLEEP);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap if (status != DDI_SUCCESS) {
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap idm_conn_rele(chan->ic_conn->ic_idmc);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap }
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap return (status);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap}
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapstatic void
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapiser_ib_post_recv_task(void *arg)
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap{
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap ibt_channel_hdl_t chanhdl = arg;
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap iser_chan_t *chan;
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap /* Pull our iSER channel handle from the private data */
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap chan = (iser_chan_t *)ibt_get_chan_private(chanhdl);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap iser_ib_post_recv(chanhdl);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap idm_conn_rele(chan->ic_conn->ic_idmc);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap}
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlapiser_ib_post_recv(ibt_channel_hdl_t chanhdl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_chan_t *chan;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_msg_t *msg;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_recv_wr_t *wrlist, wr[ISER_IB_RQ_POST_MAX];
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int rq_space, msg_ret;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int total_num, npost;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint_t nposted;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status, i;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp_t *iser_qp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Pull our iSER channel handle from the private data */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan = (iser_chan_t *)ibt_get_chan_private(chanhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap ASSERT(chan != NULL);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Bail out if the connection is closed; no need for more recv WRs */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((chan->ic_conn->ic_stage == ISER_CONN_STAGE_CLOSING) ||
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (chan->ic_conn->ic_stage == ISER_CONN_STAGE_CLOSED)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* get the QP handle from the iser_chan */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp = &chan->ic_qp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
1d73e59f8caac41c539211070dbc51318da5c71ePriya Krishnan hca = chan->ic_hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: unable to retrieve "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA handle");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* check for space to post on the RQ */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rq_space = iser_qp->rq_depth - iser_qp->rq_level;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (rq_space == 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* The RQ is full, clear the pending flag and return */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_taskqpending = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Keep track of the lowest value for rq_min_post_level */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_qp->rq_level < iser_qp->rq_min_post_level)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_min_post_level = iser_qp->rq_level;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* we've room to post, so pull from the msg cache */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap msg = iser_msg_get(hca, rq_space, &msg_ret);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (msg == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: no message handles "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "available in msg cache currently");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * There are no messages on the cache. Wait a half-
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * second, then try again.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap delay(drv_usectohz(ISER_DELAY_HALF_SECOND));
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap status = iser_ib_post_recv_async(chanhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: failed to "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "redispatch routine");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Failed to dispatch, clear pending flag */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_taskqpending = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (msg_ret != rq_space) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: requested number of "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "messages not allocated: requested (%d) allocated (%d)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rq_space, msg_ret);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* We got some, but not all, of our requested depth */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap rq_space = msg_ret;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Now, walk through the allocated WRs and post them,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * ISER_IB_RQ_POST_MAX (or less) at a time.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap wrlist = &wr[0];
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap total_num = rq_space;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap while (total_num) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* determine the number to post on this iteration */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap npost = (total_num > ISER_IB_RQ_POST_MAX) ?
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_IB_RQ_POST_MAX : total_num;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* build a list of WRs from the msg list */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (i = 0; i < npost; i++) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap wrlist[i].wr_id = (ibt_wrid_t)(uintptr_t)msg;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap wrlist[i].wr_nds = ISER_IB_SGLIST_SIZE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap wrlist[i].wr_sgl = &msg->msg_ds;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap msg = msg->nextp;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* post the list to the RQ */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nposted = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_post_recv(chanhdl, wrlist, npost, &nposted);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((status != IBT_SUCCESS) || (nposted != npost)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: ibt_post_recv "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failed: requested (%d) posted (%d) status (%d)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap npost, nposted, status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap total_num -= nposted;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* decrement total number to post by the number posted */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap total_num -= nposted;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (total_num != 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: unable to fill RQ, "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failed to post (%d) WRs", total_num);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_level += rq_space - total_num;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_level += rq_space;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Now that we've filled the RQ, check that all of the recv WRs
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * haven't just been immediately consumed. If so, taskqpending is
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * still B_TRUE, so we need to fire off a taskq thread to post
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * more WRs.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_qp->rq_level == 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
cf8c0ebaf84c824d8f14486e47457119c138ce3cPeter Dunlap status = iser_ib_post_recv_async(chanhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_post_recv: failed to "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "dispatch followup routine");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Failed to dispatch, clear pending flag */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_taskqpending = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * We're done, we've filled the RQ. Clear the taskq
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * flag so that we can run again.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_qp->rq_taskqpending = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&chan->ic_conn->ic_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_handle_portup_event()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This handles the IBT_EVENT_PORT_UP unaffiliated asynchronous event.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * To facilitate a seamless bringover of the port and configure the CM service
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * for inbound iSER service requests on this newly active port, the existing
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IDM services will be checked for iSER support.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * If an iSER service was already created, then this service will simply be
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * bound to the gid of the newly active port. If on the other hand, the CM
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * service did not exist, i.e. only socket communication, then a new CM
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * service will be first registered with the saved service parameters and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * then bound to the newly active port.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_handle_portup_event(ibt_hca_hdl_t hdl, ibt_async_event_t *event)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ib_gid_t gid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc_t *idm_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event: HCA(0x%llx) port(%d)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)event->ev_hca_guid, event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Query all ports on the HCA and update the port information
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * maintainted in the iser_hca_t structure
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_guid2hca(event->ev_hca_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* HCA is just made available, first port on that HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_alloc_hca(event->ev_hca_guid);
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan if (hca == NULL) {
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event "
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan "iser_ib_alloc_hca failed: HCA(0x%llx) port(%d)",
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan (longlong_t)event->ev_hca_guid, event->ev_port);
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan return;
a9194ad3d8097e6ebec24a00d9052b23fa1eabd2Priya Krishnan }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_insert_tail(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_num_hcas++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_update_hcaports(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status(0x%x): iser_ib_update_hcaports failed: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA(0x%llx) port(%d)", status,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)event->ev_hca_guid, event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap gid = hca->hca_port_info[event->ev_port - 1].p_sgid_tbl[0];
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Iterate through the global list of IDM target services
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and check for existing iSER CM service.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&idm.idm_global_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (idm_svc = list_head(&idm.idm_tgt_svc_list);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc = list_next(&idm.idm_tgt_svc_list, idm_svc)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idm_svc->is_iser_svc == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Establish a new CM service for iSER requests */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_tgt_svc_create(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &idm_svc->is_svc_req, idm_svc);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status(0x%x): iser_tgt_svc_create failed: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA(0x%llx) port(%d)", status,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)event->ev_hca_guid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_activate_port(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc, event->ev_hca_guid, gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status(0x%x): Bind service on port "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "(%llx:%llx) failed",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status, (longlong_t)gid.gid_prefix,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)gid.gid_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event: service bound "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA(0x%llx) port(%d)", (longlong_t)event->ev_hca_guid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&idm.idm_global_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portup_event success: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA(0x%llx) port(%d)", (longlong_t)event->ev_hca_guid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_handle_portdown_event()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This handles the IBT_EVENT_PORT_DOWN unaffiliated asynchronous error.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Unconfigure the CM service on the deactivated port and teardown the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * connections that are using the CM service.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_handle_portdown_event(ibt_hca_hdl_t hdl, ibt_async_event_t *event)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ib_gid_t gid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Query all ports on the HCA and update the port information
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * maintainted in the iser_hca_t structure
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_guid2hca(event->ev_hca_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(hca != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_update_hcaports(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portdown_event status(0x%x): "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "ibt_ib_update_hcaports failed: HCA(0x%llx) port(%d)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status, (longlong_t)event->ev_hca_guid, event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* get the gid of the new port */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap gid = hca->hca_port_info[event->ev_port - 1].p_sgid_tbl[0];
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_deactivate_port(event->ev_hca_guid, gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_portdown_event success: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA(0x%llx) port(%d)", (longlong_t)event->ev_hca_guid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap event->ev_port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_handle_hca_detach_event()
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Quiesce all activity bound for the port, teardown the connection, unbind
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iSER services on all ports and release the HCA handle.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_handle_hca_detach_event(ibt_hca_hdl_t hdl, ibt_async_event_t *event)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *nexthca, *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int i, status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_handle_hca_detach_event: HCA(0x%llx)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)event->ev_hca_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_guid2hca(event->ev_hca_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (i = 0; i < hca->hca_num_ports; i++) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_deactivate_port(hca->hca_guid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_port_info[i].p_sgid_tbl[0]);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Update the HCA list maintained in the iser_state. Free the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * resources allocated to the HCA, i.e. caches, protection domain
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (hca = list_head(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = nexthca) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nexthca = list_next(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_guid == event->ev_hca_guid) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_remove(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_num_hcas--;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_free_hca(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != DDI_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_WARN, "iser_ib_handle_hca_detach: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "Failed to free hca(%p)", (void *)hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_insert_tail(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_num_hcas++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* No way to return status to IBT if this fails */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_async_handler
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * An IBT Asynchronous Event handler is registered it with the framework and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * passed via the ibt_attach() routine. This function handles the following
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * asynchronous events.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IBT_EVENT_PORT_UP
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IBT_ERROR_PORT_DOWN
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IBT_HCA_ATTACH_EVENT
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * IBT_HCA_DETACH_EVENT
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/* ARGSUSED */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_async_handler(void *clntp, ibt_hca_hdl_t hdl, ibt_async_code_t code,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_async_event_t *event)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (code) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case IBT_EVENT_PORT_UP:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_handle_portup_event(hdl, event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case IBT_ERROR_PORT_DOWN:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_handle_portdown_event(hdl, event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case IBT_HCA_ATTACH_EVENT:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * A new HCA device is available for use, ignore this
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * event because the corresponding IBT_EVENT_PORT_UP
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * events will get triggered and handled accordingly.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case IBT_HCA_DETACH_EVENT:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_ib_handle_hca_detach_event(hdl, event);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_init_hcas
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function opens all the HCA devices, gathers the HCA state information
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and adds the HCA handle for each HCA found in the iser_soft_state.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_init_hcas(void)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ib_guid_t *guid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int num_hcas;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int i;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Retrieve the HCA list */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap num_hcas = ibt_get_hca_list(&guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (num_hcas == 0) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This shouldn't happen, but might if we have all HCAs
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * detach prior to initialization.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the hcalist lock */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_init(&iser_state->is_hcalist_lock, NULL, MUTEX_DRIVER, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Create the HCA list */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_create(&iser_state->is_hcalist, sizeof (iser_hca_t),
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap offsetof(iser_hca_t, hca_node));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (i = 0; i < num_hcas; i++) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_init_hcas: initializing HCA "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "(0x%llx)", (longlong_t)guid[i]);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = iser_ib_alloc_hca(guid[i]);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* This shouldn't happen, teardown and fail */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) iser_ib_fini_hcas();
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_hca_list(guid, num_hcas);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_insert_tail(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_num_hcas++;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Free the IBT HCA list */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_hca_list(guid, num_hcas);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Check that we've initialized at least one HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (list_is_empty(&iser_state->is_hcalist)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_init_hcas: failed to initialize "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "any HCAs");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) iser_ib_fini_hcas();
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_fini_hcas
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Teardown the iSER HCA list initialized above.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_fini_hcas(void)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *nexthca, *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (hca = list_head(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = nexthca) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap nexthca = list_next(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_remove(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = iser_ib_free_hca(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_fini_hcas: failed to free "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "HCA during fini");
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_insert_tail(&iser_state->is_hcalist, hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_state->is_num_hcas--;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_destroy(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_alloc_hca
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function opens the given HCA device, gathers the HCA state information
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * and adds the HCA handle
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_hca_t *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_alloc_hca(ib_guid_t guid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Allocate an iser_hca_t HCA handle */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = (iser_hca_t *)kmem_zalloc(sizeof (iser_hca_t), KM_SLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Open this HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_open_hca(iser_state->is_ibhdl, guid, &hca->hca_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_alloc_hca: ibt_open_hca failed:"
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap " guid (0x%llx) status (0x%x)", (longlong_t)guid, status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(hca, sizeof (iser_hca_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_guid = guid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_clnt_hdl = iser_state->is_ibhdl;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Query the HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_query_hca(hca->hca_hdl, &hca->hca_attr);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_alloc_hca: ibt_query_hca "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failure: guid (0x%llx) status (0x%x)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)guid, status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_close_hca(hca->hca_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(hca, sizeof (iser_hca_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Query all ports on the HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_query_hca_ports(hca->hca_hdl, 0,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &hca->hca_port_info, &hca->hca_num_ports,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &hca->hca_port_info_sz);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_alloc_hca: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "ibt_query_hca_ports failure: guid (0x%llx) "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status (0x%x)", (longlong_t)guid, status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_close_hca(hca->hca_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(hca, sizeof (iser_hca_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Allocate a single PD on this HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_alloc_pd(hca->hca_hdl, IBT_PD_NO_FLAGS,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap &hca->hca_pdhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_alloc_hca: ibt_alloc_pd "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "failure: guid (0x%llx) status (0x%x)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)guid, status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_close_hca(hca->hca_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_free_portinfo(hca->hca_port_info, hca->hca_port_info_sz);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(hca, sizeof (iser_hca_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the message and data MR caches for this HCA */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_init_hca_caches(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_free_hca(iser_hca_t *hca)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_hca_portinfo_t *hca_port_info;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint_t hca_port_info_sz;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(hca != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_failed)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca_port_info = hca->hca_port_info;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca_port_info_sz = hca->hca_port_info_sz;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Free the memory regions before freeing
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * the associated protection domain
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_fini_hca_caches(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_free_pd(hca->hca_hdl, hca->hca_pdhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_free_hca: failed to free PD "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status=0x%x", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap goto out_caches;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_close_hca(hca->hca_hdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_fini_hcas: failed to close HCA "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status=0x%x", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap goto out_pd;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_free_portinfo(hca_port_info, hca_port_info_sz);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(hca, sizeof (iser_hca_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * We only managed to partially tear down the HCA, try to put it back
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * like it was before returning.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapout_pd:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_alloc_pd(hca->hca_hdl, IBT_PD_NO_FLAGS, &hca->hca_pdhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_failed = B_TRUE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Report error and exit */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_free_hca: could not re-alloc PD "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "status=0x%x", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapout_caches:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_init_hca_caches(hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (DDI_FAILURE);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_update_hcaports(iser_hca_t *hca)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_hca_portinfo_t *pinfop, *oldpinfop;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uint_t size, oldsize, nport;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ASSERT(hca != NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_query_hca_ports(hca->hca_hdl, 0, &pinfop, &nport, &size);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "ibt_query_hca_ports failed: %d", status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap oldpinfop = hca->hca_port_info;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap oldsize = hca->hca_port_info_sz;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_port_info = pinfop;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca->hca_port_info_sz = size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (void) ibt_free_portinfo(oldpinfop, oldsize);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IBT_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_gid2hca
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Given a gid, find the corresponding hca
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_hca_t *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_gid2hca(ib_gid_t gid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int i;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (hca = list_head(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = list_next(&iser_state->is_hcalist, hca)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (i = 0; i < hca->hca_num_ports; i++) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((hca->hca_port_info[i].p_sgid_tbl[0].gid_prefix ==
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap gid.gid_prefix) &&
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (hca->hca_port_info[i].p_sgid_tbl[0].gid_guid ==
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap gid.gid_guid)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_guid2hca
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Given a HCA guid, find the corresponding HCA
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_hca_t *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_guid2hca(ib_guid_t guid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_hca_t *hca;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (hca = list_head(&iser_state->is_hcalist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap hca = list_next(&iser_state->is_hcalist, hca)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (hca->hca_guid == guid) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (hca);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&iser_state->is_hcalist_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_conv_sockaddr2ibtaddr
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function converts a socket address into the IBT format
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid iser_ib_conv_sockaddr2ibtaddr(
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_sockaddr_t *saddr, ibt_ip_addr_t *ibt_addr)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (saddr == NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->family = AF_UNSPEC;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->un.ip4addr = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap } else {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (saddr->sin.sa_family) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->family = saddr->sin4.sin_family;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->un.ip4addr = saddr->sin4.sin_addr.s_addr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET6:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->family = saddr->sin6.sin6_family;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->un.ip6addr = saddr->sin6.sin6_addr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_addr->family = AF_UNSPEC;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_conv_ibtaddr2sockaddr
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function converts an IBT ip address handle to a sockaddr
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid iser_ib_conv_ibtaddr2sockaddr(struct sockaddr_storage *ss,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_ip_addr_t *ibt_addr, in_port_t port)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap struct sockaddr_in *sin;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap struct sockaddr_in6 *sin6;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap switch (ibt_addr->family) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_UNSPEC:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sin = (struct sockaddr_in *)ibt_addr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sin->sin_port = ntohs(port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bcopy(sin, ss, sizeof (struct sockaddr_in));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap case AF_INET6:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sin6 = (struct sockaddr_in6 *)ibt_addr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap sin6->sin6_port = ntohs(port);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bcopy(sin6, ss, sizeof (struct sockaddr_in6));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap break;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap default:
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_conv_ibtaddr2sockaddr: "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "unknown family type: 0x%x", ibt_addr->family);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_setup_cq
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * This function sets up the Completion Queue size and allocates the specified
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Completion Queue
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_setup_cq(ibt_hca_hdl_t hca_hdl, uint_t cq_size, ibt_cq_hdl_t *cq_hdl)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_cq_attr_t cq_attr;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cq_attr.cq_size = cq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cq_attr.cq_sched = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cq_attr.cq_flags = IBT_CQ_NO_FLAGS;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Allocate a Completion Queue */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_alloc_cq(hca_hdl, &cq_attr, cq_hdl, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_setup_cq: ibt_alloc_cq failure (%d)",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (ISER_STATUS_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_setup_chanargs
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_setup_chanargs(uint8_t hca_port, ibt_cq_hdl_t scq_hdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_cq_hdl_t rcq_hdl, uint_t sq_size, uint_t rq_size,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ibt_pd_hdl_t hca_pdhdl, ibt_rc_chan_alloc_args_t *cargs)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap bzero(cargs, sizeof (ibt_rc_chan_alloc_args_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Set up the size of the channels send queue, receive queue and the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * maximum number of elements in a scatter gather list of work requests
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * posted to the send and receive queues.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_sizes.cs_sq = sq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_sizes.cs_rq = rq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_sizes.cs_sq_sgl = ISER_IB_SGLIST_SIZE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_sizes.cs_rq_sgl = ISER_IB_SGLIST_SIZE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * All Work requests signaled on a WR basis will receive a send
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * request completion.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_flags = IBT_ALL_SIGNALED;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Enable RDMA read and RDMA write on the channel end points */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_control = IBT_CEP_RDMA_RD | IBT_CEP_RDMA_WR;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the local hca port on which the channel is allocated */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_hca_port_num = hca_port;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the Send and Receive Completion Queue handles */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_scq = scq_hdl;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_rcq = rcq_hdl;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Set the protection domain associated with the channel */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_pd = hca_pdhdl;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* No SRQ usage */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap cargs->rc_srq = NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_init_qp
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Initialize the QP handle
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_init_qp(iser_chan_t *chan, uint_t sq_size, uint_t rq_size)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the handle lock */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_init(&chan->ic_qp.qp_lock, NULL, MUTEX_DRIVER, NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Record queue sizes */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.sq_size = sq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.rq_size = rq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the RQ monitoring data */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.rq_depth = rq_size;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.rq_level = 0;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.rq_lwm = (chan->ic_recvcq_sz * ISER_IB_RQ_LWM_PCT) / 100;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Initialize the taskq flag */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap chan->ic_qp.rq_taskqpending = B_FALSE;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap/*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_ib_fini_qp
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Teardown the QP handle
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapvoid
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_fini_qp(iser_qp_t *qp)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Destroy the handle lock */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_destroy(&qp->qp_lock);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic int
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_activate_port(idm_svc_t *idm_svc, ib_guid_t guid, ib_gid_t gid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_sbind_t *is_sbind;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap int status;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = idm_svc->is_iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Save the address of the service bind handle in the
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * iser_svc_t to undo the service binding at a later time
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind = kmem_zalloc(sizeof (iser_sbind_t), KM_SLEEP);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind->is_gid = gid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind->is_guid = guid;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status = ibt_bind_service(iser_svc->is_srvhdl, gid, NULL,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_svc, &is_sbind->is_sbindhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (status != IBT_SUCCESS) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap ISER_LOG(CE_NOTE, "iser_ib_activate_port: status(0x%x): "
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap "Bind service(%llx) on port(%llx:%llx) failed",
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap status, (longlong_t)iser_svc->is_svcid,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (longlong_t)gid.gid_prefix, (longlong_t)gid.gid_guid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(is_sbind, sizeof (iser_sbind_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (status);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_insert_tail(&iser_svc->is_sbindlist, is_sbind);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (IBT_SUCCESS);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic void
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_deactivate_port(ib_guid_t hca_guid, ib_gid_t gid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc_t *iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn_t *iser_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_sbind_t *is_sbind;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn_t *idm_conn;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /*
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Iterate through the global list of IDM target connections.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * Issue a TRANSPORT_FAIL for any connections on this port, and
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap * if there is a bound service running on the port, tear it down.
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_enter(&idm.idm_global_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (idm_conn = list_head(&idm.idm_tgt_conn_list);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn = list_next(&idm.idm_tgt_conn_list, idm_conn)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idm_conn->ic_transport_type != IDM_TRANSPORT_TYPE_ISER) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* this is not an iSER connection, skip it */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_conn = idm_conn->ic_transport_private;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (iser_conn->ic_chan->ic_ibt_path.pi_hca_guid != hca_guid) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* this iSER connection is on a different port */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Fail the transport for this connection */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap idm_conn_event(idm_conn, CE_TRANSPORT_FAIL, IDM_STATUS_FAIL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (idm_conn->ic_conn_type == CONN_TYPE_INI) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* initiator connection, nothing else to do */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap continue;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* Check for a service binding */
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_svc = idm_conn->ic_svc_binding->is_iser_svc;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind = iser_ib_get_bind(iser_svc, hca_guid, gid);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if (is_sbind != NULL) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap /* This service is still bound, tear it down */
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_unbind_service(iser_svc->is_srvhdl,
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind->is_sbindhdl);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap list_remove(&iser_svc->is_sbindlist, is_sbind);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap kmem_free(is_sbind, sizeof (iser_sbind_t));
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap mutex_exit(&idm.idm_global_mutex);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapstatic iser_sbind_t *
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlapiser_ib_get_bind(iser_svc_t *iser_svc, ib_guid_t hca_guid, ib_gid_t gid)
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap{
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap iser_sbind_t *is_sbind;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap for (is_sbind = list_head(&iser_svc->is_sbindlist);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind != NULL;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap is_sbind = list_next(&iser_svc->is_sbindlist, is_sbind)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap if ((is_sbind->is_guid == hca_guid) &&
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (is_sbind->is_gid.gid_prefix == gid.gid_prefix) &&
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap (is_sbind->is_gid.gid_guid == gid.gid_guid)) {
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (is_sbind);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap }
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap return (NULL);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap}