1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CDDL HEADER START
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * The contents of this file are subject to the terms of the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Common Development and Distribution License (the "License").
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * You may not use this file except in compliance with the License.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * or http://www.opensolaris.org/os/licensing.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * See the License for the specific language governing permissions
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * and limitations under the License.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * When distributing Covered Code, include this CDDL HEADER in each
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If applicable, add the following below this CDDL HEADER, with the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * fields enclosed by brackets "[]" replaced with your own identifying
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * information: Portions Copyright [yyyy] [name of copyright owner]
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * CDDL HEADER END
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * I/O Controller functions for the Solaris COMSTAR SCSI RDMA Protocol
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Target (SRPT) port provider.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/types.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/types.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sunddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/atomic.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sysmacros.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ib/ibtl/ibti.h>
191c289b86668766245f78ec1f87557319bc46a1Charles Ting#include <sys/sdt.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_impl.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_ioc.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_stp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_ch.h"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson#include "srpt_common.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_srq_size - Tunable parameter that specifies the number
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * of receive WQ entries that can be posted to the IOC shared
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * receive queue.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonuint32_t srpt_ioc_srq_size = SRPT_DEFAULT_IOC_SRQ_SIZE;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonextern uint16_t srpt_send_msg_depth;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonextern uint32_t srpt_iu_size;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonextern boolean_t srpt_enable_by_default;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* IOC profile capabilities mask must be big-endian */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesontypedef struct srpt_ioc_opcap_bits_s {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#if defined(_BIT_FIELDS_LTOH)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t af:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson at:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wt:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rt:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson st:1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#elif defined(_BIT_FIELDS_HTOL)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t st:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rt:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wt:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wf:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson at:1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson af:1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#else
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#endif
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson} srpt_ioc_opcap_bits_t;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesontypedef union {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_opcap_bits_t bits;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t mask;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson} srpt_ioc_opcap_mask_t;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * vmem arena variables - values derived from iSER
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_MR_QUANTSIZE 0x400 /* 1K */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_MIN_CHUNKSIZE 0x100000 /* 1MB */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* use less memory on 32-bit kernels as it's much more constrained */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#ifdef _LP64
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_BUF_MR_CHUNKSIZE 0x1000000 /* 16MB */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_BUF_POOL_MAX 0x40000000 /* 1GB */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#else
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_BUF_MR_CHUNKSIZE 0x400000 /* 4MB */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#define SRPT_BUF_POOL_MAX 0x4000000 /* 64MB */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#endif
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic ibt_mr_flags_t srpt_dbuf_mr_flags =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IBT_MR_ENABLE_LOCAL_WRITE | IBT_MR_ENABLE_REMOTE_WRITE |
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IBT_MR_ENABLE_REMOTE_READ;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid srpt_ioc_ib_async_hdlr(void *clnt, ibt_hca_hdl_t hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_async_code_t code, ibt_async_event_t *event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic struct ibt_clnt_modinfo_s srpt_ibt_modinfo = {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IBTI_V_CURR,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IBT_STORAGE_DEV,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_ib_async_hdlr,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson NULL,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "srpt"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson};
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_ioc_t *srpt_ioc_init(ib_guid_t guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_ioc_fini(srpt_ioc_t *ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonstatic boolean_t srpt_check_hca_cfg_enabled(ib_guid_t hca_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_vmem_pool_t *srpt_vmem_create(const char *name, srpt_ioc_t *ioc,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_memlen_t chunksize, uint64_t maxsize, ibt_mr_flags_t flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void *srpt_vmem_alloc(srpt_vmem_pool_t *vm_pool, size_t size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic int srpt_vmem_mr_compare(const void *a, const void *b);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_mr_t *srpt_vmem_chunk_alloc(srpt_vmem_pool_t *ioc,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_memlen_t chunksize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_vmem_destroy(srpt_vmem_pool_t *vm_pool);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_vmem_free(srpt_vmem_pool_t *vm_pool, void *vaddr, size_t size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_mr_t *srpt_reg_mem(srpt_vmem_pool_t *vm_pool, ib_vaddr_t vaddr,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_memlen_t len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_vmem_chunk_free(srpt_vmem_pool_t *vm_pool, srpt_mr_t *mr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_dereg_mem(srpt_ioc_t *ioc, srpt_mr_t *mr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic int srpt_vmem_mr(srpt_vmem_pool_t *vm_pool, void *vaddr, size_t size,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *mr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_attach() - I/O Controller attach
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Attach to IBTF and initialize I/O controllers. The srpt_ctxt->sc_rwlock
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * should be held outside of this call.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonint
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_attach()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int hca_cnt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int hca_ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_guid_t *guid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(srpt_ctxt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Attach to IBTF and initialize a list of IB devices. Each
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * HCA will be represented by an I/O Controller.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_attach(&srpt_ibt_modinfo, srpt_ctxt->sc_dip,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt, &srpt_ctxt->sc_ibt_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != DDI_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_attach, ibt_attach failed (0x%x)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (DDI_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson hca_cnt = ibt_get_hca_list(&guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (hca_cnt < 1) {
168665f7ddaca2a65705c3b127078ffc6b24adc3Sue Gleeson /*
168665f7ddaca2a65705c3b127078ffc6b24adc3Sue Gleeson * not a fatal error. Service will be up and
168665f7ddaca2a65705c3b127078ffc6b24adc3Sue Gleeson * waiting for ATTACH events.
168665f7ddaca2a65705c3b127078ffc6b24adc3Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_attach, no HCA found");
168665f7ddaca2a65705c3b127078ffc6b24adc3Sue Gleeson return (DDI_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (hca_ndx = 0; hca_ndx < hca_cnt; hca_ndx++) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_attach, attaching HCA %016llx",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)guid[hca_ndx]);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_attach_hca(guid[hca_ndx], B_FALSE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_free_hca_list(guid, hca_cnt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("ioc_attach, added %d I/O Controller(s)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt->sc_num_iocs);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (DDI_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Initialize I/O Controllers. sprt_ctxt->sc_rwlock must be locked by the
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * caller.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * 'checked' indicates no need to lookup the hca in the HCA configuration
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * list.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonvoid
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonsrpt_ioc_attach_hca(ib_guid_t hca_guid, boolean_t checked)
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson{
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson boolean_t enable_hca = B_TRUE;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_t *ioc;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (!checked) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson enable_hca = srpt_check_hca_cfg_enabled(hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (!enable_hca) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /* nothing to do */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2(
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "ioc_attach_hca, HCA %016llx disabled "
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "by srpt config",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_attach_hca, adding I/O"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson " Controller (%016llx)", (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson ioc = srpt_ioc_init(hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (ioc == NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * IOC already exists or an error occurred. Already
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * logged by srpt_ioc_init()
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Create the COMSTAR SRP Target for this IOC. If this fails,
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * remove the IOC.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_enter(&ioc->ioc_rwlock, RW_WRITER);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson ioc->ioc_tgt_port = srpt_stp_alloc_port(ioc, ioc->ioc_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (ioc->ioc_tgt_port == NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L1("ioc_attach_hca: alloc SCSI"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson " Target Port error on GUID(%016llx)",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)ioc->ioc_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_exit(&ioc->ioc_rwlock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_fini(ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_exit(&ioc->ioc_rwlock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * New HCA added with default SCSI Target Port, SRP service
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * will be started when SCSI Target Port is brought
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * on-line by STMF.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson list_insert_tail(&srpt_ctxt->sc_ioc_list, ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_attach_hca, I/O Controller ibt HCA hdl (%p)",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (void *)ioc->ioc_ibt_hdl);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ctxt->sc_num_iocs++;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson}
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * srpt_check_hca_cfg_enabled()
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Function to check the configuration for the enabled status of a given
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * HCA. Returns B_TRUE if SRPT services should be activated for this HCA,
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * B_FALSE if it should be disabled.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonstatic boolean_t
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonsrpt_check_hca_cfg_enabled(ib_guid_t hca_guid)
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson{
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson int status;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson char buf[32];
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson nvlist_t *hcanv;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson boolean_t enable_hca;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson enable_hca = srpt_enable_by_default;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_FORMAT_HCAKEY(buf, sizeof (buf), (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (srpt_ctxt->sc_cfg_hca_nv != NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson status = nvlist_lookup_nvlist(srpt_ctxt->sc_cfg_hca_nv,
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson buf, &hcanv);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (status == 0) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L3("check_hca_cfg, found guid %s", buf);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (void) nvlist_lookup_boolean_value(hcanv,
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_PROP_ENABLED, &enable_hca);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson } else {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L3("check_hca_cfg, did not find guid %s",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson buf);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return (enable_hca);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson}
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * srpt_ioc_update()
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Using the configuration nvlist, enables or disables SRP services
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * the provided HCAs. srpt_ctxt->sc_rwlock should be held outside of this call.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonvoid
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonsrpt_ioc_update(void)
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson{
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson boolean_t enabled;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson nvpair_t *nvp = NULL;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson uint64_t hca_guid;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson nvlist_t *nvl;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson nvlist_t *cfg = srpt_ctxt->sc_cfg_hca_nv;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (cfg == NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_update, no configuration data");
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson while ((nvp = nvlist_next_nvpair(cfg, nvp)) != NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson enabled = srpt_enable_by_default;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if ((nvpair_value_nvlist(nvp, &nvl)) != 0) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_update, did not find an nvlist");
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson continue;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if ((nvlist_lookup_uint64(nvl, SRPT_PROP_GUID, &hca_guid))
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson != 0) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_update, did not find a guid");
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson continue;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (void) nvlist_lookup_boolean_value(nvl, SRPT_PROP_ENABLED,
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson &enabled);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (enabled) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_update, enabling guid %016llx",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_attach_hca(hca_guid, B_TRUE);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson } else {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_update, disabling guid %016llx",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_detach_hca(hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson}
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_detach() - I/O Controller detach
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ctxt->sc_rwlock should be held outside of this call.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_detach()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * All SRP targets must be destroyed before calling this
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * function.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while ((ioc = list_head(&srpt_ctxt->sc_ioc_list)) != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_detach, removing I/O Controller(%p)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " (%016llx), ibt_hdl(%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ioc,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc ? (u_longlong_t)ioc->ioc_guid : 0x0ll,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ioc->ioc_ibt_hdl);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson list_remove(&srpt_ctxt->sc_ioc_list, ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_fini(ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ctxt->sc_num_iocs--;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt->sc_ibt_hdl = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * srpt_ioc_detach_hca()
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Stop SRP Target services on this HCA
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Note that this is not entirely synchronous with srpt_ioc_attach_hca()
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * in that we don't need to check the configuration to know whether to
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * disable an HCA. We get here either because the IB framework has told
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * us the HCA has been detached, or because the administrator has explicitly
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * disabled this HCA.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson *
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Must be called with srpt_ctxt->sc_rwlock locked as RW_WRITER.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonvoid
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonsrpt_ioc_detach_hca(ib_guid_t hca_guid)
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson{
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_t *ioc;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_target_port_t *tgt;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson stmf_status_t stmf_status = STMF_SUCCESS;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson ioc = srpt_ioc_get_locked(hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (ioc == NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /* doesn't exist, nothing to do */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_enter(&ioc->ioc_rwlock, RW_WRITER);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson tgt = ioc->ioc_tgt_port;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (tgt != NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson stmf_status = srpt_stp_destroy_port(tgt);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (stmf_status == STMF_SUCCESS) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson ioc->ioc_tgt_port = NULL;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (void) srpt_stp_free_port(tgt);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_exit(&ioc->ioc_rwlock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (stmf_status != STMF_SUCCESS) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /* should never happen */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson list_remove(&srpt_ctxt->sc_ioc_list, ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ctxt->sc_num_iocs--;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_fini(ioc);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_detach_hca, HCA %016llx detached",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson}
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_init() - I/O Controller initialization
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Requires srpt_ctxt->rw_lock be held outside of call.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_ioc_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_init(ib_guid_t guid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_hca_attr_t hca_attr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t iu_ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t err_ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_mr_attr_t mr_attr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_mr_desc_t mr_desc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_srq_sizes_t srq_attr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson char namebuf[32];
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson size_t iu_offset;
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson uint_t srq_sz;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_query_hca_byguid(guid, &hca_attr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, HCA query error (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = srpt_ioc_get_locked(guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc != NULL) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("ioc_init, HCA already exists");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = kmem_zalloc(sizeof (srpt_ioc_t), KM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_init(&ioc->ioc_rwlock, NULL, RW_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&ioc->ioc_rwlock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(&hca_attr, &ioc->ioc_attr, sizeof (ibt_hca_attr_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_init, HCA max mr=%d, mrlen=%lld",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson hca_attr.hca_max_memr, (u_longlong_t)hca_attr.hca_max_memr_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_guid = guid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_open_hca(srpt_ctxt->sc_ibt_hdl, guid, &ioc->ioc_ibt_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, IBT open failed (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto hca_open_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_alloc_pd(ioc->ioc_ibt_hdl, IBT_PD_NO_FLAGS,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ioc->ioc_pd_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, IBT create PD failed (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto pd_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We require hardware support for SRQs. We use a common SRQ to
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * reduce channel memory consumption.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((ioc->ioc_attr.hca_flags & IBT_HCA_SRQ) == 0) {
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson SRPT_DPRINTF_L0(
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson "ioc_init, no SRQ capability, HCA not supported");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srq_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("ioc_init, Using shared receive queues, max srq work"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " queue size(%d), def size = %d", ioc->ioc_attr.hca_max_srqs_sz,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_srq_size);
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson srq_sz = srq_attr.srq_wr_sz = min(srpt_ioc_srq_size,
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson ioc->ioc_attr.hca_max_srqs_sz) - 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srq_attr.srq_sgl_sz = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_alloc_srq(ioc->ioc_ibt_hdl, IBT_SRQ_NO_FLAGS,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_pd_hdl, &srq_attr, &ioc->ioc_srq_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ioc->ioc_srq_attr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, IBT create SRQ failed(%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srq_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson SRPT_DPRINTF_L2("ioc_init, Using SRQ size(%d), MAX SG size(%d)",
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson srq_sz, 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_set_srq_private(ioc->ioc_srq_hdl, ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Allocate a pool of SRP IU message buffers and post them to
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the I/O Controller SRQ. We let the SRQ manage the free IU
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * messages.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson ioc->ioc_num_iu_entries = srq_sz;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_iu_pool = kmem_zalloc(sizeof (srpt_iu_t) *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries, KM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson ioc->ioc_iu_bufs = kmem_alloc(srpt_iu_size *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries, KM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((ioc->ioc_iu_pool == NULL) || (ioc->ioc_iu_bufs == NULL)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, failed to allocate SRQ IUs");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srq_iu_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_vaddr = (ib_vaddr_t)(uintptr_t)ioc->ioc_iu_bufs;
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson mr_attr.mr_len = srpt_iu_size * ioc->ioc_num_iu_entries;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_as = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_flags = IBT_MR_ENABLE_LOCAL_WRITE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_register_mr(ioc->ioc_ibt_hdl, ioc->ioc_pd_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &mr_attr, &ioc->ioc_iu_mr_hdl, &mr_desc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, IU buffer pool MR err(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srq_iu_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (iu_ndx = 0, iu = ioc->ioc_iu_pool; iu_ndx <
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries; iu_ndx++, iu++) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson iu_offset = (iu_ndx * srpt_iu_size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_buf = (void *)((uintptr_t)ioc->ioc_iu_bufs + iu_offset);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_init(&iu->iu_lock, NULL, MUTEX_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_sge.ds_va = mr_desc.md_vaddr + iu_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_sge.ds_key = mr_desc.md_lkey;
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson iu->iu_sge.ds_len = srpt_iu_size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_ioc = ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_pool_ndx = iu_ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_ioc_post_recv_iu(ioc, &ioc->ioc_iu_pool[iu_ndx]);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, SRQ IU post err(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srq_iu_post_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Initialize the dbuf vmem arena
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void) snprintf(namebuf, sizeof (namebuf),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "srpt_buf_pool_%16llX", (u_longlong_t)guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_dbuf_pool = srpt_vmem_create(namebuf, ioc,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_BUF_MR_CHUNKSIZE, SRPT_BUF_POOL_MAX, srpt_dbuf_mr_flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_dbuf_pool == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto stmf_db_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Allocate the I/O Controller STMF data buffer allocator. The
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * data store will span all targets associated with this IOC.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_stmf_ds = stmf_alloc(STMF_STRUCT_DBUF_STORE, 0, 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_stmf_ds == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_attach, STMF DBUF alloc failure for IOC");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto stmf_db_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_stmf_ds->ds_alloc_data_buf = &srpt_ioc_ds_alloc_dbuf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_stmf_ds->ds_free_data_buf = &srpt_ioc_ds_free_dbuf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_stmf_ds->ds_port_private = ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ioc->ioc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_db_alloc_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_dbuf_pool != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_destroy(ioc->ioc_dbuf_pool);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrq_iu_post_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_mr_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_deregister_mr(ioc->ioc_ibt_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_iu_mr_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, error deregistering"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " memory region (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (err_ndx = 0, iu = ioc->ioc_iu_pool; err_ndx < iu_ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson err_ndx++, iu++) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrq_iu_alloc_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_bufs != NULL) {
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson kmem_free(ioc->ioc_iu_bufs, srpt_iu_size *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_pool != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(ioc->ioc_iu_pool,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_iu_t) * ioc->ioc_num_iu_entries);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_srq_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_free_srq(ioc->ioc_srq_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, error freeing SRQ (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrq_alloc_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_free_pd(ioc->ioc_ibt_hdl, ioc->ioc_pd_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, free PD error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonpd_alloc_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_close_hca(ioc->ioc_ibt_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_init, close ioc error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonhca_open_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ioc->ioc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_destroy(&ioc->ioc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(ioc, sizeof (*ioc));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_fini() - I/O Controller Cleanup
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Requires srpt_ctxt->sc_rwlock be held outside of call.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_fini(srpt_ioc_t *ioc)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int ndx;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Note driver flows will have already taken all SRP
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * services running on the I/O Controller off-line.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
b1d7ec75953cd517f5b7c3d9cb427ff8ec5d7d07Peter Cudhea - Oracle Corporation - Burlington, MA United States ASSERT(ioc->ioc_tgt_port == NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&ioc->ioc_rwlock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_ibt_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_stmf_ds != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(ioc->ioc_stmf_ds);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_srq_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("ioc_fini, freeing SRQ");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_free_srq(ioc->ioc_srq_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_fini, free SRQ"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_mr_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_deregister_mr(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_ibt_hdl, ioc->ioc_iu_mr_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_fini, error deregistering"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " memory region (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_bufs != NULL) {
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson kmem_free(ioc->ioc_iu_bufs, srpt_iu_size *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_iu_pool != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("ioc_fini, freeing IU entries");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (ndx = 0; ndx < ioc->ioc_num_iu_entries; ndx++) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&ioc->ioc_iu_pool[ndx].iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("ioc_fini, free IU pool struct");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(ioc->ioc_iu_pool,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_iu_t) * (ioc->ioc_num_iu_entries));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_iu_pool = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_num_iu_entries = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_dbuf_pool != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_destroy(ioc->ioc_dbuf_pool);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_pd_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_free_pd(ioc->ioc_ibt_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_pd_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_fini, free PD"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_close_hca(ioc->ioc_ibt_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "ioc_fini, close ioc error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ioc->ioc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_destroy(&ioc->ioc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(ioc, sizeof (srpt_ioc_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_port_active() - I/O Controller port active
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_port_active(ibt_async_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson srpt_target_port_t *tgt = NULL;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson boolean_t online_target = B_FALSE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson stmf_change_status_t cstatus;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(event != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("ioc_port_active event handler, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Find the HCA in question and if the HCA has completed
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * initialization, and the SRP Target service for the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the I/O Controller exists, then bind this port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = srpt_ioc_get(event->ev_hca_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_port_active, I/O Controller not"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " active");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt = ioc->ioc_tgt_port;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_port_active, no I/O Controller target"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " undefined");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We take the target lock here to serialize this operation
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * with any STMF initiated target state transitions. If
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SRP is off-line then the service handle is NULL.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson mutex_enter(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (tgt->tp_ibt_svc_hdl != NULL) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson status = srpt_ioc_svc_bind(tgt, event->ev_port);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if ((status != IBT_SUCCESS) &&
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (status != IBT_HCA_PORT_NOT_ACTIVE)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_port_active, bind failed (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson } else {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson /* if we were offline because of no ports, try onlining now */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if ((tgt->tp_num_active_ports == 0) &&
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (tgt->tp_requested_state != tgt->tp_state) &&
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (tgt->tp_requested_state == SRPT_TGT_STATE_ONLINE)) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson online_target = B_TRUE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson cstatus.st_completion_status = STMF_SUCCESS;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson cstatus.st_additional_info = "port active";
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson mutex_exit(&tgt->tp_lock);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (online_target) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson stmf_status_t ret;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson ret = stmf_ctl(STMF_CMD_LPORT_ONLINE, tgt->tp_lport, &cstatus);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (ret == STMF_SUCCESS) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1("ioc_port_active, port %d active, "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "target %016llx online requested", event->ev_port,
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)ioc->ioc_guid);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson } else if (ret != STMF_ALREADY) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1("ioc_port_active, port %d active, "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "target %016llx failed online request: %d",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson event->ev_port, (u_longlong_t)ioc->ioc_guid,
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (int)ret);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_port_down()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_port_down(ibt_async_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_target_port_t *tgt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *next_ch;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson boolean_t offline_target = B_FALSE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson stmf_change_status_t cstatus;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("ioc_port_down event handler, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Find the HCA in question and if the HCA has completed
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * initialization, and the SRP Target service for the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the I/O Controller exists, then logout initiators
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * through this port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = srpt_ioc_get(event->ev_hca_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_port_down, I/O Controller not"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " active");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We only have one target now, but we could go through all
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SCSI target ports if more are added.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt = ioc->ioc_tgt_port;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_port_down, no I/O Controller target"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " undefined");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * For all channel's logged in through this port, initiate a
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * disconnect.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = list_head(&tgt->tp_ch_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while (ch != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson next_ch = list_next(&tgt->tp_ch_list, ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch->ch_session && (ch->ch_session->ss_hw_port ==
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson event->ev_port)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_disconnect(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = next_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_num_active_ports--;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson /* if we have no active ports, take the target offline */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if ((tgt->tp_num_active_ports == 0) &&
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (tgt->tp_state == SRPT_TGT_STATE_ONLINE)) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson cstatus.st_completion_status = STMF_SUCCESS;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson cstatus.st_additional_info = "no ports active";
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson offline_target = B_TRUE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (offline_target) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson stmf_status_t ret;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson ret = stmf_ctl(STMF_CMD_LPORT_OFFLINE, tgt->tp_lport, &cstatus);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (ret == STMF_SUCCESS) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1("ioc_port_down, port %d down, target "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "%016llx offline requested", event->ev_port,
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)ioc->ioc_guid);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson } else if (ret != STMF_ALREADY) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1("ioc_port_down, port %d down, target "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "%016llx failed offline request: %d",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson event->ev_port,
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)ioc->ioc_guid, (int)ret);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_ib_async_hdlr - I/O Controller IB asynchronous events
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_ib_async_hdlr(void *clnt, ibt_hca_hdl_t hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_async_code_t code, ibt_async_event_t *event)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson switch (code) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_EVENT_PORT_UP:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_port_active(event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_ERROR_PORT_DOWN:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_port_down(event);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_HCA_ATTACH_EVENT:
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2(
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "ib_async_hdlr, received attach event for HCA 0x%016llx",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)event->ev_hca_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_attach_hca(event->ev_hca_guid, B_FALSE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&srpt_ctxt->sc_rwlock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_HCA_DETACH_EVENT:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1(
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "ioc_iob_async_hdlr, received HCA_DETACH_EVENT for "
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "HCA 0x%016llx",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)event->ev_hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson srpt_ioc_detach_hca(event->ev_hca_guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson rw_exit(&srpt_ctxt->sc_rwlock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case IBT_EVENT_EMPTY_CHAN:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* Channel in ERROR state is now empty */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = (srpt_channel_t *)ibt_get_chan_private(event->ev_chan_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "ioc_iob_async_hdlr, received empty channel error on %p",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson default:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_ib_async_hdlr, event not "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "handled (%d)", code);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_svc_bind()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonibt_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_svc_bind(srpt_target_port_t *tgt, uint_t portnum)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_hw_port_t *port;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_hca_portinfo_t *portinfo;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t qportinfo_sz;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t qportnum;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_gid_t new_gid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srpt_session_t sess;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt->tp_ioc != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = tgt->tp_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ibt_svc_hdl == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, NULL SCSI target port"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " service");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_INVALID_PARAM);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (portnum == 0 || portnum > tgt->tp_nports) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, bad port (%d)", portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_INVALID_PARAM);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_query_hca_ports(ioc->ioc_ibt_hdl, portnum,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &portinfo, &qportnum, &qportinfo_sz);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("ioc_svc_bind, query port error (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_INVALID_PARAM);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(portinfo != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If port is not active do nothing, caller should attempt to bind
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * after the port goes active.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (portinfo->p_linkstate != IBT_PORT_ACTIVE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, port %d not in active state",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_free_portinfo(portinfo, qportinfo_sz);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_HCA_PORT_NOT_ACTIVE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson port = &tgt->tp_hw_port[portnum-1];
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson new_gid = portinfo->p_sgid_tbl[0];
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_free_portinfo(portinfo, qportinfo_sz);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If previously bound and the port GID has changed,
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson * unbind the old GID.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (port->hwp_bind_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (new_gid.gid_guid != port->hwp_gid.gid_guid ||
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson new_gid.gid_prefix != port->hwp_gid.gid_prefix) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, unregister current"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " bind");
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_unbind_service(tgt->tp_ibt_svc_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson port->hwp_bind_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson port->hwp_bind_hdl = NULL;
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson } else {
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, port %d already bound",
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson /* bind the new port GID */
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson if (port->hwp_bind_hdl == NULL) {
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_bind, bind service, %016llx:%016llx",
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson (u_longlong_t)new_gid.gid_prefix,
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson (u_longlong_t)new_gid.gid_guid);
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson /*
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson * Pass SCSI Target Port as CM private data, the target will
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson * always exist while this service is bound.
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson */
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson status = ibt_bind_service(tgt->tp_ibt_svc_hdl, new_gid, NULL,
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson tgt, &port->hwp_bind_hdl);
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson if (status != IBT_SUCCESS && status != IBT_CM_SERVICE_EXISTS) {
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson SRPT_DPRINTF_L1("ioc_svc_bind, bind error (%d)",
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson status);
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson return (status);
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson }
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson port->hwp_gid.gid_prefix = new_gid.gid_prefix;
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson port->hwp_gid.gid_guid = new_gid.gid_guid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson
285c05bcaff47f0043483452c70351ad34aeb880Sue Gleeson /* port is now active */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_num_active_ports++;
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
191c289b86668766245f78ec1f87557319bc46a1Charles Ting /* setting up a transient structure for the dtrace probe. */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting bzero(&sess, sizeof (srpt_session_t));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(sess.ss_t_gid, new_gid.gid_prefix, new_gid.gid_guid);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(sess.ss_t_name, tgt->tp_ibt_svc_id);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_1(service__up, srpt_session_t, &sess);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_svc_unbind()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_svc_unbind(srpt_target_port_t *tgt, uint_t portnum)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_hw_port_t *port;
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srpt_session_t sess;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson ibt_status_t ret;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_unbind, SCSI target does not exist");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (portnum == 0 || portnum > tgt->tp_nports) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_unbind, bad port (%d)", portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson port = &tgt->tp_hw_port[portnum-1];
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting /* setting up a transient structure for the dtrace probe. */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting bzero(&sess, sizeof (srpt_session_t));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(sess.ss_t_gid, port->hwp_gid.gid_prefix,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting port->hwp_gid.gid_guid);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(sess.ss_t_name, tgt->tp_ibt_svc_id);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_1(service__down, srpt_session_t, &sess);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ibt_svc_hdl != NULL && port->hwp_bind_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_unbind, unregister current bind");
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson ret = ibt_unbind_service(tgt->tp_ibt_svc_hdl,
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli port->hwp_bind_hdl);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (ret != IBT_SUCCESS) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1(
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "ioc_svc_unbind, unregister port %d failed: %d",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson portnum, ret);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson } else {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson port->hwp_bind_hdl = NULL;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson port->hwp_gid.gid_prefix = 0;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson port->hwp_gid.gid_guid = 0;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_svc_unbind_all()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_svc_unbind_all(srpt_target_port_t *tgt)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t portnum;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_svc_unbind_all, NULL SCSI target port"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " specified");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (portnum = 1; portnum <= tgt->tp_nports; portnum++) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_svc_unbind(tgt, portnum);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_get_locked()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Requires srpt_ctxt->rw_lock be held outside of call.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_get_locked(ib_guid_t guid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = list_head(&srpt_ctxt->sc_ioc_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while (ioc != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_guid == guid) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = list_next(&srpt_ctxt->sc_ioc_list, ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_get()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_get(ib_guid_t guid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&srpt_ctxt->sc_rwlock, RW_READER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = srpt_ioc_get_locked(guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&srpt_ctxt->sc_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_post_recv_iu()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonibt_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_post_recv_iu(srpt_ioc_t *ioc, srpt_iu_t *iu)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_recv_wr_t wr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t posted;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ioc != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_id = (ibt_wrid_t)(uintptr_t)iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_nds = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_sgl = &iu->iu_sge;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson posted = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_post_srq(ioc->ioc_srq_hdl, &wr, 1, &posted);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_post_recv_iu, post error (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_repost_recv_iu()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_repost_recv_iu(srpt_ioc_t *ioc, srpt_iu_t *iu)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(mutex_owned(&iu->iu_lock));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Some additional sanity checks while in debug state, all STMF
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * related task activities should be complete prior to returning
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * this IU to the available pool.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu->iu_stmf_task == NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu->iu_sq_posted_cnt == 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = iu->iu_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_ch = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_num_rdescs = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_rdescs = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_tot_xfer_len = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_tag = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_flags = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_sq_posted_cnt = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_ioc_post_recv_iu(ioc, iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Very bad, we should initiate a shutdown of the I/O
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Controller here, off-lining any targets associated
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * with this I/O Controller (and therefore disconnecting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * any logins that remain).
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * In practice this should never happen so we put
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the code near the bottom of the implementation list.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L0("ioc_repost_recv_iu, error RX IU (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (ch != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson atomic_inc_32(&ch->ch_req_lim_delta);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_init_profile()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SRP I/O Controller serialization lock must be held when this
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * routine is invoked.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_init_profile(srpt_ioc_t *ioc)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_opcap_mask_t capmask = {0};
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ioc != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_guid = h2b64(ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void) memcpy(ioc->ioc_profile.ioc_id_string,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "Solaris SRP Target 0.9a", 23);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Note vendor ID and subsystem ID are 24 bit values. Low order
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * 8 bits in vendor ID field is slot and is initialized to zero.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Low order 8 bits of subsystem ID is a reserved field and
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * initialized to zero.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_vendorid =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b32((uint32_t)(ioc->ioc_attr.hca_vendor_id << 8));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_deviceid =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b32((uint32_t)ioc->ioc_attr.hca_device_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_device_ver =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b16((uint16_t)ioc->ioc_attr.hca_version_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_subsys_vendorid =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b32((uint32_t)(ioc->ioc_attr.hca_vendor_id << 8));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_subsys_id = h2b32(0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_io_class = h2b16(SRP_REV_16A_IO_CLASS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_io_subclass = h2b16(SRP_IO_SUBCLASS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_protocol = h2b16(SRP_PROTOCOL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_protocol_ver = h2b16(SRP_PROTOCOL_VERSION);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_send_msg_qdepth = h2b16(srpt_send_msg_depth);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_rdma_read_qdepth =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_attr.hca_max_rdma_out_chan;
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson ioc->ioc_profile.ioc_send_msg_sz = h2b32(srpt_iu_size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_rdma_xfer_sz = h2b32(SRPT_DEFAULT_MAX_RDMA_SIZE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson capmask.bits.st = 1; /* Messages can be sent to IOC */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson capmask.bits.sf = 1; /* Messages can be sent from IOC */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson capmask.bits.rf = 1; /* RDMA Reads can be sent from IOC */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson capmask.bits.wf = 1; /* RDMA Writes can be sent from IOC */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_ctrl_opcap_mask = capmask.mask;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We currently only have one target, but if we had a list we would
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * go through that list and only count those that are ONLINE when
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * setting the services count and entries.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_tgt_port->tp_srp_enabled) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_service_entries = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_svc.srv_id = h2b64(ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void) snprintf((char *)ioc->ioc_svc.srv_name,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IB_DM_MAX_SVC_NAME_LEN, "SRP.T10:%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_profile.ioc_service_entries = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_svc.srv_id = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_ioc_ds_alloc_dbuf()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_data_buf_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_ds_alloc_dbuf(struct scsi_task *task, uint32_t size,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t *pminsize, uint32_t flags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ds_dbuf_t *dbuf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_data_buf_t *stmf_dbuf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *buf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t mr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(task != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu = task->task_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = iu->iu_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("ioc_ds_alloc_dbuf, invoked ioc(%p)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " size(%d), flags(%x)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ioc, size, flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson buf = srpt_vmem_alloc(ioc->ioc_dbuf_pool, size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (buf == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (srpt_vmem_mr(ioc->ioc_dbuf_pool, buf, size, &mr) != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto stmf_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf = stmf_alloc(STMF_STRUCT_DATA_BUF, sizeof (srpt_ds_dbuf_t),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (stmf_dbuf == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("ioc_ds_alloc_dbuf, stmf_alloc failed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto stmf_alloc_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf = stmf_dbuf->db_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_stmf_buf = stmf_dbuf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_mr_hdl = mr.mr_hdl;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_ioc = ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_sge.ds_va = mr.mr_va;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_sge.ds_key = mr.mr_lkey;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_sge.ds_len = size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_buf_size = size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_data_size = size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_relative_offset = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_flags = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_xfer_status = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_sglist_length = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_sglist[0].seg_addr = buf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_dbuf->db_sglist[0].seg_length = size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (stmf_dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonbuf_mr_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(stmf_dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_alloc_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_free(ioc->ioc_dbuf_pool, buf, size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_ioc_ds_free_dbuf(struct stmf_dbuf_store *ds,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_data_buf_t *dbuf)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("ioc_ds_free_dbuf, invoked buf (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = ds->ds_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_free(ioc->ioc_dbuf_pool, dbuf->db_sglist[0].seg_addr,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_buf_size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* Memory arena routines */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_vmem_pool_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_create(const char *name, srpt_ioc_t *ioc, ib_memlen_t chunksize,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint64_t maxsize, ibt_mr_flags_t flags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *chunk;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_pool_t *result;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(chunksize <= maxsize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result = kmem_zalloc(sizeof (srpt_vmem_pool_t), KM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_ioc = ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_chunksize = chunksize;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_max_size = maxsize;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_flags = flags;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_init(&result->svp_lock, NULL, RW_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_create(&result->svp_mr_list, srpt_vmem_mr_compare,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_mr_t), offsetof(srpt_mr_t, mr_avl));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk = srpt_vmem_chunk_alloc(result, chunksize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_add(&result->svp_mr_list, chunk);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_total_size = chunksize;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->svp_vmem = vmem_create(name,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void*)(uintptr_t)chunk->mr_va,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (size_t)chunk->mr_len, SRPT_MR_QUANTSIZE,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson NULL, NULL, NULL, 0, VM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (result);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_destroy(srpt_vmem_pool_t *vm_pool)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *chunk;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *next;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&vm_pool->svp_lock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson vmem_destroy(vm_pool->svp_vmem);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk = avl_first(&vm_pool->svp_mr_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while (chunk != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson next = AVL_NEXT(&vm_pool->svp_mr_list, chunk);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_remove(&vm_pool->svp_mr_list, chunk);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_chunk_free(vm_pool, chunk);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk = next;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_destroy(&vm_pool->svp_mr_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&vm_pool->svp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_destroy(&vm_pool->svp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(vm_pool, sizeof (srpt_vmem_pool_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_alloc(srpt_vmem_pool_t *vm_pool, size_t size)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *result;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *next;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_memlen_t chunklen;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(vm_pool != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result = vmem_alloc(vm_pool->svp_vmem, size,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson VM_NOSLEEP | VM_FIRSTFIT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (result != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* memory successfully allocated */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (result);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* need more vmem */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&vm_pool->svp_lock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunklen = vm_pool->svp_chunksize;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (vm_pool->svp_total_size >= vm_pool->svp_max_size) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* no more room to alloc */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&vm_pool->svp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((vm_pool->svp_total_size + chunklen) > vm_pool->svp_max_size) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunklen = vm_pool->svp_max_size - vm_pool->svp_total_size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson next = srpt_vmem_chunk_alloc(vm_pool, chunklen);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (next != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Note that the size of the chunk we got
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * may not be the size we requested. Use the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * length returned in the chunk itself.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (vmem_add(vm_pool->svp_vmem, (void*)(uintptr_t)next->mr_va,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson next->mr_len, VM_NOSLEEP) == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_vmem_chunk_free(vm_pool, next);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("vmem_add failed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson vm_pool->svp_total_size += next->mr_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_add(&vm_pool->svp_mr_list, next);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&vm_pool->svp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result = vmem_alloc(vm_pool->svp_vmem, size, VM_NOSLEEP | VM_FIRSTFIT);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (result);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_free(srpt_vmem_pool_t *vm_pool, void *vaddr, size_t size)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson vmem_free(vm_pool->svp_vmem, vaddr, size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic int
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_mr(srpt_vmem_pool_t *vm_pool, void *vaddr, size_t size,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *mr)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson avl_index_t where;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_vaddr_t mrva = (ib_vaddr_t)(uintptr_t)vaddr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t chunk;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *nearest;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_vaddr_t chunk_end;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int status = DDI_FAILURE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&vm_pool->svp_lock, RW_READER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk.mr_va = mrva;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson nearest = avl_find(&vm_pool->svp_mr_list, &chunk, &where);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (nearest == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson nearest = avl_nearest(&vm_pool->svp_mr_list, where,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson AVL_BEFORE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (nearest != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* Verify this chunk contains the specified address range */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(nearest->mr_va <= mrva);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk_end = nearest->mr_va + nearest->mr_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (chunk_end >= mrva + size) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr->mr_hdl = nearest->mr_hdl;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr->mr_va = mrva;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr->mr_len = size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr->mr_lkey = nearest->mr_lkey;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr->mr_rkey = nearest->mr_rkey;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = DDI_SUCCESS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&vm_pool->svp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_mr_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_chunk_alloc(srpt_vmem_pool_t *vm_pool, ib_memlen_t chunksize)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *chunk = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *result = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while ((chunk == NULL) && (chunksize >= SRPT_MIN_CHUNKSIZE)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunk = kmem_alloc(chunksize, KM_NOSLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (chunk == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("srpt_vmem_chunk_alloc: "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "failed to alloc chunk of %d, trying %d",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (int)chunksize, (int)chunksize/2);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunksize /= 2;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (chunk != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result = srpt_reg_mem(vm_pool, (ib_vaddr_t)(uintptr_t)chunk,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson chunksize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (result == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("srpt_vmem_chunk_alloc: "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "chunk registration failed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(chunk, chunksize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (result);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_chunk_free(srpt_vmem_pool_t *vm_pool, srpt_mr_t *mr)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *chunk = (void *)(uintptr_t)mr->mr_va;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ib_memlen_t chunksize = mr->mr_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_dereg_mem(vm_pool->svp_ioc, mr);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(chunk, chunksize);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic srpt_mr_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_reg_mem(srpt_vmem_pool_t *vm_pool, ib_vaddr_t vaddr, ib_memlen_t len)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *result = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_mr_attr_t mr_attr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_mr_desc_t mr_desc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc = vm_pool->svp_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result = kmem_zalloc(sizeof (srpt_mr_t), KM_NOSLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (result == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("srpt_reg_mem: failed to allocate");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bzero(&mr_attr, sizeof (ibt_mr_attr_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bzero(&mr_desc, sizeof (ibt_mr_desc_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_vaddr = vaddr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_len = len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_as = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mr_attr.mr_flags = vm_pool->svp_flags;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_register_mr(ioc->ioc_ibt_hdl, ioc->ioc_pd_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &mr_attr, &result->mr_hdl, &mr_desc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("srpt_reg_mem: ibt_register_mr "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "failed %d", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(result, sizeof (srpt_mr_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->mr_va = mr_attr.mr_vaddr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->mr_len = mr_attr.mr_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->mr_lkey = mr_desc.md_lkey;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson result->mr_rkey = mr_desc.md_rkey;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (result);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_dereg_mem(srpt_ioc_t *ioc, srpt_mr_t *mr)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_deregister_mr(ioc->ioc_ibt_hdl, mr->mr_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L1("srpt_dereg_mem, error deregistering MR (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(mr, sizeof (srpt_mr_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic int
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_vmem_mr_compare(const void *a, const void *b)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *mr1 = (srpt_mr_t *)a;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_mr_t *mr2 = (srpt_mr_t *)b;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* sort and match by virtual address */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (mr1->mr_va < mr2->mr_va) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (-1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (mr1->mr_va > mr2->mr_va) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}