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 * SCSI Target Port I/F for Solaris SCSI RDMA Protocol Target (SRP)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * port provider module for the COMSTAR framework.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/cpuvar.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/types.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/conf.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/stat.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/file.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sunddi.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/modctl.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sysmacros.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/sdt.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/taskq.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/atomic.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf_ioctl.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/portif.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan#include <sys/scsi/generic/persist.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include <sys/ib/mgt/ibdma/ibdma.h>
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_impl.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_cm.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_ioc.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_ch.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson#include "srpt_stp.h"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonextern srpt_ctxt_t *srpt_ctxt;
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleesonextern uint32_t srpt_iu_size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * STMF LPort Interface Prototypes
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t srpt_stp_xfer_data(struct scsi_task *task,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson struct stmf_data_buf *dbuf, uint32_t ioflags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_status_t srpt_stp_send_status(struct scsi_task *task,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t ioflags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_stp_task_free(struct scsi_task *task);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t srpt_stp_abort(struct stmf_local_port *lport,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int abort_cmd, void *arg, uint32_t flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_stp_task_poll(struct scsi_task *task);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_stp_ctl(struct stmf_local_port *lport,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int cmd, void *arg);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t srpt_stp_info(uint32_t cmd,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson struct stmf_local_port *lport, void *arg, uint8_t *buf,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t *bufsizep);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_stp_event_handler(struct stmf_local_port *lport,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int eventid, void *arg, uint32_t flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_format_login_rsp(srp_login_req_t *req,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_rsp_t *rsp, uint8_t flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_format_login_rej(srp_login_req_t *req,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_rej_t *rej, uint32_t reason);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic scsi_devid_desc_t *srpt_stp_alloc_scsi_devid_desc(uint64_t guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonextern uint16_t srpt_send_msg_depth;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_start_srp() - Start SRP service
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Enable the SRP service for the specified SCSI Target Port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonint
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_start_srp(srpt_target_port_t *tgt)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibdma_status_t dma_status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson int port;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_start_srp, NULL SCSI target port");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_start_srp, SCSI target port NULL"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " IOC pointer");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = tgt->tp_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_start_srp, register SRP service for"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " svc_id (%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_register_service(srpt_ctxt->sc_ibt_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &tgt->tp_ibt_svc_desc, tgt->tp_ibt_svc_id, 1,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &tgt->tp_ibt_svc_hdl, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_hdl = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_start_srp, SRP service creation err (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Bind the service associated with the SCSI target port to
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * each active port of the I/O Controller.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson for (port = 0; port < ioc->ioc_attr.hca_nports; port++) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_ioc_svc_bind(tgt, port+1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS &&
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status != IBT_HCA_PORT_NOT_ACTIVE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("start_srp, Unable to bind"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " service (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srp_start_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson /* don't online if we have no active ports */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (tgt->tp_num_active_ports == 0) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L2("start_srp, no ports active for svc_id %016llx",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)tgt->tp_ibt_svc_id);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson status = IBT_HCA_PORT_NOT_ACTIVE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson goto srp_start_err;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_srp_enabled = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Calculate the new I/O Controller profile and either update the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * profile if previously registered or register it with the IB
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Device Management Agent.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("start_srp, update I/O Controller profile (%016llx)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_init_profile(ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_ibdma_hdl == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_ibdma_hdl =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt->sc_ibdma_ops.ibdma_register(ioc->ioc_guid,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ioc->ioc_profile, &ioc->ioc_svc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_ibdma_hdl == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("start_srp, Unable to register"
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson " I/O Profile for svc_id %016llx",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)tgt->tp_ibt_svc_id);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson status = IBT_FAILURE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srp_start_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dma_status =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt->sc_ibdma_ops.ibdma_update(ioc->ioc_ibdma_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ioc->ioc_profile, &ioc->ioc_svc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (dma_status != IBDMA_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("start_srp, Unable to update I/O"
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson " Profile for svc_id %016llxi (%d)",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)tgt->tp_ibt_svc_id, dma_status);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson status = IBT_FAILURE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto srp_start_err;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (IBT_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrp_start_err:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_srp_enabled = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_svc_unbind_all(tgt);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_num_active_ports = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ibt_svc_hdl != NULL) {
aedf2b3bb56b025fcaf87b49ec6c8aeea07f16d7srivijitha dugganapalli (void) ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_hdl = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_stop_srp() - Stop SRP service.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Disable the SRP service on the specified SCSI Target Port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_stop_srp(srpt_target_port_t *tgt)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibdma_status_t dma_status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_stop_srp, NULL SCSI Target Port"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " specified");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_stop_srp, bad Target, IOC NULL");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = tgt->tp_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Update the I/O Controller profile to remove the SRP service
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * for this SCSI target port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_srp_enabled = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_ibdma_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_stop_srp, update I/O Controller"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " profile (%016llx)", (u_longlong_t)ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_init_profile(ioc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc->ioc_profile.ioc_service_entries == 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_stop_srp, no services active"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " unregister IOC profile");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ctxt->sc_ibdma_ops.ibdma_unregister(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_ibdma_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_ibdma_hdl = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dma_status = srpt_ctxt->sc_ibdma_ops.ibdma_update(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc->ioc_ibdma_hdl, &ioc->ioc_profile,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ioc->ioc_svc);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (dma_status != IBDMA_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_stop_srp, Unable to"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " update I/O Profile (%d)", dma_status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Unbind the SRP service associated with the SCSI target port
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * from all of the I/O Controller physical ports.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_stop_srp, unbind and de-register service"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "(%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ibt_svc_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_svc_unbind_all(tgt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_ibt_svc_hdl != NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_hdl);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_stop_srp, de-register service"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error(%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_hdl = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SRP service is now off-line for this SCSI Target Port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We force a disconnect (i.e. SRP Target Logout) for any
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * active SRP logins.
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 SRPT_DPRINTF_L3("stp_stop_srp, disconnect ch(%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_disconnect(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = list_next(&tgt->tp_ch_list, ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * wait for all sessions to terminate before returning
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while (!list_is_empty(&tgt->tp_sess_list)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_wait(&tgt->tp_sess_complete, &tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_alloc_port() - Allocate SCSI Target Port
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_target_port_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_alloc_port(srpt_ioc_t *ioc, ib_guid_t guid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_target_port_t *tgt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_local_port_t *lport;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint64_t temp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_alloc_port, NULL I/O Controller");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_port, allocate STMF local port");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport = stmf_alloc(STMF_STRUCT_STMF_LOCAL_PORT, sizeof (*tgt), 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (lport == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("tgt_alloc_port, stmf_alloc failed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt = lport->lport_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_init(&tgt->tp_lock, NULL, MUTEX_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_init(&tgt->tp_ch_list_lock, NULL, MUTEX_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_init(&tgt->tp_offline_complete, NULL, CV_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_create(&tgt->tp_ch_list, sizeof (srpt_channel_t),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson offsetof(srpt_channel_t, ch_stp_node));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_init(&tgt->tp_sess_list_lock, NULL, MUTEX_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_init(&tgt->tp_sess_complete, NULL, CV_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_create(&tgt->tp_sess_list, sizeof (srpt_session_t),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson offsetof(srpt_session_t, ss_node));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_drv_disabled = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_srp_enabled = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_lport = lport;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ioc = ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_id = guid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_desc.sd_handler = srpt_cm_hdlr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_ibt_svc_desc.sd_flags = IBT_SRV_NO_FLAGS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson temp = h2b64(tgt->tp_ibt_svc_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(&temp, &tgt->tp_srp_port_id[0], 8);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson temp = h2b64(tgt->tp_ioc->ioc_guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(&temp, &tgt->tp_srp_port_id[8], 8);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_nports = ioc->ioc_attr.hca_nports;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_hw_port =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_zalloc(sizeof (srpt_hw_port_t) * tgt->tp_nports, KM_SLEEP);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_num_active_ports = 0;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_scsi_devid = srpt_stp_alloc_scsi_devid_desc(tgt->tp_ibt_svc_id);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_id = tgt->tp_scsi_devid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_pp = srpt_ctxt->sc_pp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_ds = ioc->ioc_stmf_ds;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_xfer_data = &srpt_stp_xfer_data;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_send_status = &srpt_stp_send_status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_task_free = &srpt_stp_task_free;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_abort = &srpt_stp_abort;
2d361592ba6a66373470f9586a66dac706951772Sue Gleeson lport->lport_abort_timeout = 300; /* 5 minutes */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_task_poll = &srpt_stp_task_poll;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_ctl = &srpt_stp_ctl;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_info = &srpt_stp_info;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport->lport_event_handler = &srpt_stp_event_handler;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte /* set up as alua participating port */
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte stmf_set_port_alua(lport);
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_port, register STMF LPORT");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonretry_registration:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = stmf_register_local_port(lport);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status == STMF_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_port, LPORT successfully"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " registered");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (tgt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status == STMF_BUSY) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * This is only done on an administrative thread of
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * execution so it is ok to take a while.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_port, delaying");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson delay(2 * drv_usectohz(1000000));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto retry_registration;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_alloc_port, STMF register local port err(0x%llx)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_port, free STMF local port");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_destroy(&tgt->tp_offline_complete);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_hw_port) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(tgt->tp_hw_port,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_hw_port_t) * tgt->tp_nports);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_scsi_devid) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(lport);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_free_port() - Free SCSI Target Port
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_free_port(srpt_target_port_t *tgt)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(list_is_empty(&tgt->tp_sess_list));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(list_is_empty(&tgt->tp_ch_list));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_destroy(&tgt->tp_ch_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_destroy(&tgt->tp_sess_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_destroy(&tgt->tp_sess_complete);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_destroy(&tgt->tp_offline_complete);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_destroy(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_free_port, free STMF local port");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_hw_port) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(tgt->tp_hw_port,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_hw_port_t) * tgt->tp_nports);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_scsi_devid) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(tgt->tp_lport);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * srpt_stp_destroy_port()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_status_t
c3a558e7c77127215b010652905be7916ec5a080Sue Gleesonsrpt_stp_destroy_port(srpt_target_port_t *tgt)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_status_t status;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson stmf_change_status_t cstatus;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson uint64_t guid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt->tp_lport != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L3("stp_destroy_port, de-register STMF LPORT");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson mutex_enter(&tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (tgt->tp_drv_disabled != 0) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /* already being destroyed, get out now - should not happen */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson mutex_exit(&tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson return (STMF_ALREADY);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson tgt->tp_drv_disabled = 1;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson guid = tgt->tp_ioc->ioc_guid;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson mutex_exit(&tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L2("stp_destroy_port: unbind and de-register"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson " services for GUID(%016llx)", (u_longlong_t)guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson cstatus.st_completion_status = STMF_SUCCESS;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson cstatus.st_additional_info = NULL;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson status = stmf_ctl(STMF_CMD_LPORT_OFFLINE, tgt->tp_lport, &cstatus);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Wait for asynchronous target off-line operation
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * to complete and then deregister the target
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson mutex_enter(&tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson while (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson cv_wait(&tgt->tp_offline_complete, &tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson mutex_exit(&tgt->tp_lock);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L3("stp_destroy_port: IOC (0x%016llx) Target"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson " SRP off-line complete", (u_longlong_t)guid);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /* loop waiting for all I/O to drain */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson for (;;) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson status = stmf_deregister_local_port(tgt->tp_lport);
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (status == STMF_BUSY) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson delay(drv_usectohz(1000000));
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson } else {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson break;
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson }
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson if (status == STMF_SUCCESS) {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L3("stp_destroy_port, LPORT de-register"
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson " complete");
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson } else {
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson /*
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson * Something other than a BUSY error, this should not happen.
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson */
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson SRPT_DPRINTF_L1(
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson "stp_destroy_port, de-register STMF error(0x%llx)",
c3a558e7c77127215b010652905be7916ec5a080Sue Gleeson (u_longlong_t)status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_xfer_data()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_xfer_data(struct scsi_task *task, struct stmf_data_buf *dbuf,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t ioflags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ds_dbuf_t *db;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_send_wr_t wr;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_wr_ds_t ds;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t xfer_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t xferred_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t rdma_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t base_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t desc_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_direct_desc_t *desc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_xfer_data, invoked task (%p), dbuf (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)task, (void *)dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu = task->task_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu->iu_ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We should use iu->iu_ch->ch_swqe_posted to throttle
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * send wqe posting. This is very unlikely because we limit
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the maximum number of initiator descriptors per IU (impact
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * of fragmentation of intiator buffer space) but it could occur
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * if the back-end (STMF) were to use too many small buffers. In
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * that case we would want to return STMF_BUSY.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_flags (0x%x)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_data_size (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_data_size);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_relative_offset (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson dbuf->db_relative_offset);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT((dbuf->db_flags & (DB_DIRECTION_TO_RPORT |
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson DB_DIRECTION_FROM_RPORT)) != (DB_DIRECTION_TO_RPORT |
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson DB_DIRECTION_FROM_RPORT));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson db = dbuf->db_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Check to see if request will overflow the remote buffer; if so
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * return a bad status and let STMF abort the task.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((dbuf->db_relative_offset + dbuf->db_data_size) >
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_tot_xfer_len) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_xfer_data, overflow of remote buffer");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson db->db_iu = iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_trans = IBT_RC_SRV;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_opcode = (dbuf->db_flags & DB_DIRECTION_TO_RPORT) ?
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson IBT_WRC_RDMAW : IBT_WRC_RDMAR;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_nds = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_sgl = &ds;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We know that the data transfer is within the bounds described
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * by our list of remote buffer descriptors. Find the starting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * point based on the offset for the transfer, then perform the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * RDMA operations required of this transfer.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson base_offset = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson desc = iu->iu_rdescs;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while ((base_offset + desc->dd_len) < dbuf->db_relative_offset) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson base_offset += desc->dd_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson desc++;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson xfer_len = dbuf->db_data_size;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson xferred_len = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson desc_offset = dbuf->db_relative_offset - base_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = iu->iu_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If the channel is no longer connected then return an
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * error and do not initiate I/O. STMF should abort the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * task.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&ch->ch_rwlock, RW_READER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (iu->iu_ch->ch_state == SRPT_CHANNEL_DISCONNECTING) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&iu->iu_ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson while (xfer_len > 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rdma_len = desc->dd_len - desc_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * We only generate completion entries on the last IB
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * operation associated with any STMF buffer.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (rdma_len >= xfer_len) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rdma_len = xfer_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_flags = IBT_WR_SEND_SIGNAL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_flags = IBT_WR_NO_FLAGS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr.rc.rcwr.rdma.rdma_raddr = desc->dd_vaddr + desc_offset;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr.rc.rcwr.rdma.rdma_rkey = desc->dd_hdl;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ds.ds_va = db->db_sge.ds_va + xferred_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ds.ds_key = db->db_sge.ds_key;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ds.ds_len = rdma_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_xfer_data, post RDMA operation");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If this task is being aborted or has been aborted,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * do not post additional I/O.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
7830165bb404e703a4653a49ad9fe110003bde03Charles Ting DTRACE_SRP_8(xfer__start, srpt_channel_t, ch,
7830165bb404e703a4653a49ad9fe110003bde03Charles Ting ibt_wr_ds_t, &(db->db_sge), srpt_iu_t, iu,
7830165bb404e703a4653a49ad9fe110003bde03Charles Ting ibt_send_wr_t, &wr, uint32_t, rdma_len,
7830165bb404e703a4653a49ad9fe110003bde03Charles Ting uint32_t, xferred_len, uint32_t, desc_offset,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting uint32_t, wr.wr_opcode == IBT_WRC_RDMAR ? 0 : 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((iu->iu_flags & (SRPT_IU_SRP_ABORTING |
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_IU_STMF_ABORTING | SRPT_IU_ABORTED)) != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&iu->iu_ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If a non-error CQE will be requested, add a reference to
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the IU and initialize the work request appropriately.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_id = srpt_ch_alloc_swqe_wrid(ch,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_SWQE_TYPE_DATA, (void *)dbuf);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (wr.wr_id == 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&iu->iu_ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_BUSY);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson atomic_inc_32(&iu->iu_sq_posted_cnt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson wr.wr_id = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = ibt_post_send(iu->iu_ch->ch_chan_hdl, &wr, 1, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Could not post to IB transport, report to STMF and
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * and let it initiate an abort of the task.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_xfer_data, post RDMA"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error (%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_free_swqe_wrid(ch, wr.wr_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson atomic_dec_32(&iu->iu_sq_posted_cnt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&iu->iu_ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson xferred_len += rdma_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson xfer_len -= rdma_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson desc_offset = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson desc++;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&ch->ch_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_send_mgmt_response() - Return SRP task managment response IU
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonibt_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_send_mgmt_response(srpt_iu_t *iu, uint8_t srp_rsp,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint_t fence)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_rsp_t *rsp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_rsp_data_t *data;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t rsp_length;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t *bufp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(mutex_owned(&iu->iu_lock));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp = iu->iu_buf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bzero(rsp, SRP_RSP_SIZE + sizeof (srp_rsp_data_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_type = SRP_IU_RSP;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Report ULP credits we have added since last response sent
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * over this channel.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_req_limit_delta =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_tag = iu->iu_tag;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* srp_rsp_t is padded out, so use explicit size here */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_length = SRP_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (srp_rsp != SRP_TM_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_flags |= SRP_RSP_VALID;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson data = (srp_rsp_data_t *)bufp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson data->rd_rsp_status = srp_rsp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_data_len = h2b32(sizeof (srp_rsp_data_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_length += sizeof (srp_rsp_data_t);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_send_mgmt_response, sending on ch(%p),"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " iu(%p), mgmt status(%d)", (void *)iu->iu_ch,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)iu, srp_rsp);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting int8_t, srp_rsp);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_send_mgmt_response, post "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "response err(%d)", status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_send_response() - Send SRP command response IU
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonibt_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_send_response(srpt_iu_t *iu, uint8_t scsi_status,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t flags, uint32_t resid, uint16_t sense_length,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t *sense_data, uint_t fence)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_rsp_t *rsp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t rsp_length;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t *bufp;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(mutex_owned(&iu->iu_lock));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp = iu->iu_buf;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bzero(rsp, SRP_RSP_SIZE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_type = SRP_IU_RSP;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Report ULP credits we have added since last response sent
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * over this channel.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_req_limit_delta =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_tag = iu->iu_tag;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_status = scsi_status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_length = SRP_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (resid != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_flags |= flags;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((flags & SRP_RSP_DO_OVER) ||
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (flags & SRP_RSP_DO_UNDER)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_do_resid_cnt = h2b32(resid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if ((flags & SRP_RSP_DI_OVER) ||
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (flags & SRP_RSP_DI_UNDER)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_di_resid_cnt = h2b32(resid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (sense_length != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_flags |= SRP_RSP_SNS_VALID;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (SRP_RSP_SIZE + sense_length >
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_ch->ch_ti_iu_len) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sense_length = iu->iu_ch->ch_ti_iu_len -
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_RSP_SIZE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(sense_data, bufp, sense_length);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->rsp_sense_data_len = h2b32(sense_length);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_length += sense_length;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L4("stp_send_reponse, sending on ch(%p),"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " iu(%p), length(%d)", (void *)iu->iu_ch,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)iu, rsp_length);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting uint8_t, scsi_status);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_send_response, post response err(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_send_status()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstmf_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_send_status(struct scsi_task *task, uint32_t ioflags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ibt_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(task != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu = task->task_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson mutex_enter(&iu->iu_lock);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu->iu_ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_send_status, invoked task (%p)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_completion_status (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_resid (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_status_ctrl (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_scsi_status (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_sense_length (%d)"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ", task_sense_data (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)task,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (int)task->task_completion_status,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_resid,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_status_ctrl,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_scsi_status,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_sense_length,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)task->task_sense_data);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_4(scsi__response, srpt_channel_t, iu->iu_ch,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_rsp_t, iu->iu_buf, scsi_task_t, task,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting int8_t, task->task_scsi_status);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson if ((iu->iu_flags & (SRPT_IU_STMF_ABORTING |
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson SRPT_IU_SRP_ABORTING | SRPT_IU_ABORTED)) != 0) {
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson mutex_exit(&iu->iu_lock);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson return (STMF_FAILURE);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson }
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Indicate future aborts can not be initiated (although
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * we will handle any that have been requested since the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * last I/O completed and before we are sending status).
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_flags |= SRPT_IU_RESP_SENT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Send SRP command response or SRP task mgmt response.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (task->task_mgmt_function == 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t rsp_flags = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t resbytes = 0;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (task->task_status_ctrl == TASK_SCTRL_OVER) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson resbytes = task->task_resid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (task->task_flags & TF_READ_DATA) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "stp_send_status, data out overrun");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags |= SRP_RSP_DO_OVER;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (task->task_flags & TF_WRITE_DATA) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "stp_send_status, data in overrun");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags |= SRP_RSP_DI_OVER;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (task->task_status_ctrl == TASK_SCTRL_UNDER) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson resbytes = task->task_resid;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (task->task_flags & TF_READ_DATA) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "stp_send_status, data out underrun");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags |= SRP_RSP_DO_UNDER;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (task->task_flags & TF_WRITE_DATA) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3(
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "stp_send_status, data in underrun");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags |= SRP_RSP_DI_UNDER;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_stp_send_response(iu,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_scsi_status, rsp_flags, resbytes,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task->task_sense_length, task->task_sense_data, 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_stp_send_mgmt_response(iu,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (task->task_scsi_status ?
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_TM_FAILED : SRP_TM_SUCCESS),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_FENCE_SEND);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If we have an error posting the response return bad status
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * to STMF and let it initiate an abort for the task.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_send_status, post response err(%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson /* clear the response sent flag since it never went out */
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson iu->iu_flags &= ~SRPT_IU_RESP_SENT;
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_FAILURE);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_task_free() - STMF call-back.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_task_free(struct scsi_task *task)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_task_free, invoked task (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)task);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu = task->task_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = iu->iu_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch->ch_session != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Do not hold IU lock while task is being removed from
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the session list - possible deadlock if cleaning up
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * channel when this is called.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_remove_task(ch->ch_session, iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_stmf_task = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_release_ref(ch, 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_abort() - STMF call-back.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_abort(struct stmf_local_port *lport, int abort_cmd,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *arg, uint32_t flags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson struct scsi_task *task;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_iu_t *iu;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_abort, invoked lport (%p), arg (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)lport, (void *)arg);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson task = (struct scsi_task *)arg;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(task != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu = (srpt_iu_t *)task->task_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(iu != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If no I/O is outstanding then immediately transition to
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson * aborted state. If any I/O is in progress OR we've sent the
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson * completion response, then indicate that an STMF abort has been
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson * requested and ask STMF to call us back later to complete the abort.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson if ((iu->iu_flags & SRPT_IU_RESP_SENT) ||
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson (iu->iu_sq_posted_cnt > 0)) {
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson SRPT_DPRINTF_L3("stp_abort, deferring abort request. "
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson "%d outstanding I/O for IU %p",
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson iu->iu_sq_posted_cnt, (void *)iu);
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson iu->iu_flags |= SRPT_IU_STMF_ABORTING;
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson status = STMF_BUSY;
6527ba5141349c7745f5bbd93541fc251914bffaSue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_abort, no outstanding I/O for %p",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson iu->iu_flags |= SRPT_IU_ABORTED;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* Synchronous abort - STMF will call task_free */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = STMF_ABORT_SUCCESS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
2d361592ba6a66373470f9586a66dac706951772Sue Gleeson mutex_exit(&iu->iu_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_task_poll() - STMF call-back
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_task_poll(struct scsi_task *task)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_task_poll, invoked, task (%p)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void *)task);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_ctl() - STMF call-back
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_ctl(struct stmf_local_port *lport, int cmd, void *arg)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_state_change_info_t *sc_info = arg;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_change_status_t cstatus;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_target_port_t *tgt;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson char *why;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(sc_info != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(lport != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt = lport->lport_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt->tp_ioc != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson why = sc_info->st_additional_info;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (why == NULL) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson why = "<null>";
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, invoked for LPORT (0x%016llx), cmd (%d), "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "info (%s)", (u_longlong_t)tgt->tp_ibt_svc_id, cmd, why);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_SUCCESS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_additional_info = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson switch (cmd) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case STMF_CMD_LPORT_ONLINE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE command,"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * If the SCSI Target Port is not enabled by the driver,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * don't start and instead return busy. This is a
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * creation/destruction transitional state and the will
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * either go away or become enabled.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_requested_state = SRPT_TGT_STATE_ONLINE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_drv_disabled != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_ctl, set LPORT_ONLINE failed - "
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson "LPORT (0x%016llx) BUSY",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)tgt->tp_ibt_svc_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_BUSY;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson } else if ((tgt->tp_state == SRPT_TGT_STATE_ONLINE) ||
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (tgt->tp_state == SRPT_TGT_STATE_ONLINING)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_ALREADY;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_INVALID_ARG;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_ONLINING;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = srpt_stp_start_srp(tgt);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (status != IBT_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_INVALID_ARG;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (tgt->tp_num_active_ports == 0) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L1(
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "stp_ctl, no ports active "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "for HCA 0x%016llx. Target will "
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson "not be placed online.",
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (u_longlong_t)tgt->tp_ibt_svc_id);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_ctl, (0x%016llx) LPORT_ONLINE command"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " status (0x%llx)", (u_longlong_t)tgt->tp_ibt_svc_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)cstatus.st_completion_status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &cstatus);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != STMF_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_ctl, ONLINE_COMPLETE returned"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error(0x%llx)", (u_longlong_t)status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case STMF_CMD_LPORT_OFFLINE:
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE command,"
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson /*
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson * Only keep persistent state if explicitly requested by user
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson * action, such as stmfadm offline-target or
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson * svcadm disable stmf.
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson * If not requested by the user, this was likely triggered by
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson * not having any HCA ports active.
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson */
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if (sc_info->st_rflags & STMF_RFLAG_USER_REQUEST) {
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson }
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson if ((tgt->tp_state == SRPT_TGT_STATE_OFFLINE) ||
3baa0db47b1b400bbbd8b7ae9ccb32bfdd1ad865Sue Gleeson (tgt->tp_state == SRPT_TGT_STATE_OFFLINING)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_ALREADY;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cstatus.st_completion_status = STMF_INVALID_ARG;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_OFFLINING;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_stop_srp(tgt);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_ctl, notify STMF OFFLINE complete"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " (0x%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson lport, &cstatus);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != STMF_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_ctl, OFFLINE_COMPLETE returned"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " error(0x%llx)", (u_longlong_t)status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case STMF_ACK_LPORT_ONLINE_COMPLETE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE_COMPLETE ACK from"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " STMF");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_state == SRPT_TGT_STATE_ONLINING) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT is ONLINE");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_ONLINE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT not on-lining");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case STMF_ACK_LPORT_OFFLINE_COMPLETE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE_COMPLETE ACK from"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " STMF");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_state == SRPT_TGT_STATE_OFFLINING) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT is OFFLINE");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_broadcast(&tgt->tp_offline_complete);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson } else {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, LPORT not off-lining");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson default:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_ctl, cmd (%d) not handled",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cmd);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_info() - STMF call-back
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic stmf_status_t
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_info(uint32_t cmd, struct stmf_local_port *lport,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *arg, uint8_t *buf, uint32_t *bufsizep)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_info, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (STMF_SUCCESS);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_event_handler() - STMF call-back
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/* ARGSUSED */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_event_handler(struct stmf_local_port *lport, int eventid,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson void *arg, uint32_t flags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_event_handler, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_alloc_scsi_devid_desc()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Allocate and initialize a SCSI device ID descriptor for
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the SRP protocol. Names are eui.GUID format.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Both extension and guid are passed in host order.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic scsi_devid_desc_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_alloc_scsi_devid_desc(uint64_t guid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson scsi_devid_desc_t *sdd;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd = kmem_zalloc(sizeof (*sdd) + SRPT_EUI_ID_LEN + 1, KM_SLEEP);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd->protocol_id = PROTOCOL_SRP;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd->piv = 1;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd->code_set = CODE_SET_ASCII;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd->association = ID_IS_TARGET_PORT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sdd->ident_length = SRPT_EUI_ID_LEN;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (void) sprintf((char *)sdd->ident, "eui.%016llX", (u_longlong_t)guid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (sdd);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_free_scsi_devid_desc()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Free a SRPT SCSI device ID descriptor previously allocated via
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_alloc_scsi_devid_desc().
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson kmem_free(sdd, sizeof (*sdd) + SRPT_EUI_ID_LEN + 1);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_alloc_session()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_session_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_alloc_session(srpt_target_port_t *tgt,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting uint8_t *i_id, uint8_t *t_id, uint8_t port,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting char *local_gid, char *remote_gid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_status_t status;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_session_t *ss;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_scsi_session_t *stmf_ss;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint64_t i_guid;
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan scsi_srp_transport_id_t *srptpd;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_alloc_session, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson i_guid = BE_IN64(&i_id[8]);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson sizeof (srpt_session_t), 0);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (stmf_ss == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_alloc_session, stmf_alloc"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " returned NULL");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ss = stmf_ss->ss_port_private;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ss != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_init(&ss->ss_rwlock, NULL, RW_DRIVER, NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_create(&ss->ss_task_list, sizeof (srpt_iu_t),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson offsetof(srpt_iu_t, iu_ss_task_node));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_ss->ss_rport_id = srpt_stp_alloc_scsi_devid_desc(i_guid);
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan /* Setup remote port transport id */
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan stmf_ss->ss_rport = stmf_remote_port_alloc(
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan sizeof (scsi_srp_transport_id_t));
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan stmf_ss->ss_rport->rport_tptid->protocol_id = PROTOCOL_SRP;
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan stmf_ss->ss_rport->rport_tptid->format_code = 0;
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan srptpd = (scsi_srp_transport_id_t *)stmf_ss->ss_rport->rport_tptid;
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan bcopy(i_id, srptpd->srp_name, SRP_PORT_ID_LEN);
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_ss->ss_lport = tgt->tp_lport;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ss->ss_ss = stmf_ss;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ss->ss_hw_port = port;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ss->ss_tgt = tgt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(i_id, ss->ss_i_id, SRP_PORT_ID_LEN);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson bcopy(t_id, ss->ss_t_id, SRP_PORT_ID_LEN);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Set the alias to include the initiator extension, this will enable
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the administrator to identify multiple unique sessions originating
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * from the same initiator.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting (void) strlcpy(ss->ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting (void) strlcpy(ss->ss_t_gid, local_gid, SRPT_ALIAS_LEN);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(ss->ss_i_name, BE_IN64(&ss->ss_i_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(ss->ss_t_name, BE_IN64(&ss->ss_t_id[0]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(ss->ss_i_alias, BE_IN64(&ss->ss_i_id[0]),
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&ss->ss_i_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(ss->ss_t_alias, BE_IN64(&ss->ss_t_id[0]),
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&ss->ss_t_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting stmf_ss->ss_rport_alias = ss->ss_i_alias;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson status = stmf_register_scsi_session(tgt->tp_lport, stmf_ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (status != STMF_SUCCESS) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_alloc_session, STMF register session"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " err(0x%llx)", (u_longlong_t)status);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_destroy(&ss->ss_task_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_destroy(&ss->ss_rwlock);
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan stmf_remote_port_free(stmf_ss->ss_rport);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(stmf_ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_insert_tail(&tgt->tp_sess_list, ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_free_session()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_free_session(srpt_session_t *session)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_scsi_session_t *stmf_ss;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_target_port_t *tgt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(session != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson tgt = session->ss_tgt;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_free_session, invoked");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_ss = session->ss_ss;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_destroy(&session->ss_task_list);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_destroy(&session->ss_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_deregister_scsi_session(tgt->tp_lport, stmf_ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan stmf_remote_port_free(stmf_ss->ss_rport);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_remove(&tgt->tp_sess_list, session);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson cv_signal(&tgt->tp_sess_complete);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_sess_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson stmf_free(stmf_ss);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_login() - SRP SCSI Target port login
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_channel_t *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_login(srpt_target_port_t *tgt, srp_login_req_t *login,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srp_login_rsp_t *login_rsp, srp_login_rej_t *login_rej,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting uint8_t login_port, char *local_gid, char *remote_gid)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t reason;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t req_it_ui_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t rsp_flags;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ioc_t *ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *ch = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_channel_t *next_ch = NULL;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_session_t *session = NULL;
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srpt_session_t sess;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(tgt != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(login != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(login_rsp != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(login_rej != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting /* Store the string representation of connection info */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting /* for Dtrace probes */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting bzero(&sess, sizeof (srpt_session_t));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting (void) strlcpy(sess.ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting (void) strlcpy(sess.ss_t_gid, local_gid, SRPT_ALIAS_LEN);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(sess.ss_i_name,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_initiator_port_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting EUI_STR(sess.ss_t_name,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_target_port_id[0]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(sess.ss_i_alias,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_initiator_port_id[0]),
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_initiator_port_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting ALIAS_STR(sess.ss_t_alias,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_target_port_id[0]),
191c289b86668766245f78ec1f87557319bc46a1Charles Ting BE_IN64(&login->lreq_target_port_id[8]));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_2(login__command, srpt_session_t, &sess,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_login_req_t, login);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * The target lock taken here serializes logins to this target
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * and prevents an STMF target port from starting a control
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * operation to transition the target state while a login is
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * being processed.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
191c289b86668766245f78ec1f87557319bc46a1Charles Ting bzero(login_rsp, sizeof (srp_login_rsp_t));
191c289b86668766245f78ec1f87557319bc46a1Charles Ting bzero(login_rej, sizeof (srp_login_rej_t));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ioc = tgt->tp_ioc;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ioc == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L1("stp_login, NULL I/O Controller");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Validate that the SRP Target ID in the login request specifies
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * this I/O Controller SCSI Target Port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (memcmp(login->lreq_target_port_id, tgt->tp_srp_port_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_PORT_ID_LEN) != 0) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, SRP CM SVC target ID mismatch."
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " Incoming TgtID 0x%016llx:0x%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, SRP Login target not on-line");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Initiator requested IU size must be as large as the specification
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * minimum and no greater than what we chose to support.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req_it_ui_len = b2h32(login->lreq_req_it_iu_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, requested iu size = %d", req_it_ui_len);
989ca64074b057b3d4318ab11e83a49b3a4b1d4bSue Gleeson if (req_it_ui_len > srpt_iu_size) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too large",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req_it_ui_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (req_it_ui_len < SRP_MIN_IU_SIZE) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too small",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson req_it_ui_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_NO_REASON;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, login req InitID 0x%016llx:0x%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[0]),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[8]));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, login req TgtID 0x%016llx:0x%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Processing is based on either single channel or multi-channel
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * operation. In single channel, all current logins for this
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * same I_T_Nexus should be logged out. In multi-channel
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * mode we would add an additional channel to an existing
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * I_T_Nexus if one currently exists (i.e. reference the
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * same SCSI session).
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags = SRP_MULTI_CH_RESULT_NO_EXISTING;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson switch (login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case SRP_LOGIN_MULTI_CH_SINGLE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Only a single channel may be associated with a I_T_Nexus.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Disconnect any channel with the same SRP Initiator and
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * SRP target IDs.
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 SRPT_DPRINTF_L3("stp_login, compare session,"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " ch_state(%d)", ch->ch_state);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson next_ch = list_next(&tgt->tp_ch_list, ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_state != SRPT_CHANNEL_CONNECTED) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_login, compare session,"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " channel not active");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = next_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson continue;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(ch->ch_session != NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_login, compare session"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " I_ID 0x%016llx:0x%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)b2h64(*((uint64_t *)(void *)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ch->ch_session->ss_i_id[0])),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)b2h64(*((uint64_t *)(void *)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ch->ch_session->ss_i_id[8])));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L3("stp_login, compare session"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " T_ID 0x%016llx:0x%016llx",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)b2h64(*((uint64_t *)(void *)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ch->ch_session->ss_t_id[0])),
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (u_longlong_t)b2h64(*((uint64_t *)(void *)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson &ch->ch_session->ss_t_id[8])));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if ((bcmp(login->lreq_initiator_port_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_session->ss_i_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_PORT_ID_LEN) == 0) &&
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson (bcmp(login->lreq_target_port_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_session->ss_t_id,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_PORT_ID_LEN) == 0)) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * if a session is in the process of connecting,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * reject subsequent equivalent requests.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch->ch_state == SRPT_CHANNEL_CONNECTING) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_INIT_CH_LIMIT;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, terminate"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " existing login");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp_flags =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRP_MULTI_CH_RESULT_TERM_EXISTING;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_disconnect(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = next_ch;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* Create the new session for this SRP login */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson session = srpt_stp_alloc_session(tgt,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson login->lreq_initiator_port_id,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting login->lreq_target_port_id, login_port,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting local_gid, remote_gid);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (session == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, session allocation"
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson " failed");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson break;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson case SRP_LOGIN_MULTI_CH_MULTIPLE:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, multichannel not supported yet");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_MULTI_CH_NOT_SUPPORTED;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* break via goto */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson default:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, invalid multichannel field (%d)",
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_NO_REASON;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* break via goto */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Create new RDMA channel for this SRP login request.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * The channel is returned with a single reference which
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * represents the reference held by the CM.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch = srpt_ch_alloc(tgt, login_port);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson if (ch == NULL) {
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, unable to alloc RDMA channel");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson reason = SRP_LOGIN_REJ_INSUFFICIENT_CH_RESOURCES;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_stp_free_session(session);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson goto reject_login;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson }
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_session = session;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ch->ch_ti_iu_len = b2h32(login->lreq_req_it_iu_len);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Add another reference to the channel which represents
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * a reference placed by the target port and add it to
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * the store of channels logged in for this target port.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_add_ref(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_enter(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_insert_tail(&tgt->tp_ch_list, ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_ch_list_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_format_login_rsp(login, login_rsp, rsp_flags);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson SRPT_DPRINTF_L2("stp_login, login successful");
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_3(login__response, srpt_session_t, &sess,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej)
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonreject_login:
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_format_login_rej(login, login_rej, reason);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson mutex_exit(&tgt->tp_lock);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_3(login__response, srpt_session_t, &sess,
191c289b86668766245f78ec1f87557319bc46a1Charles Ting srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson return (NULL);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_logout() - SRP logout
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson *
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * Logout is not normally initiated in-band, but is so, just
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * initiate a disconnect.
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_logout(srpt_channel_t *ch)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
191c289b86668766245f78ec1f87557319bc46a1Charles Ting DTRACE_SRP_1(logout__command, srpt_channel_t, ch);
191c289b86668766245f78ec1f87557319bc46a1Charles Ting SRPT_DPRINTF_L2("stp_logout, invoked for ch (%p)", (void *)ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson srpt_ch_disconnect(ch);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_format_login_rej() - Format login reject IU
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_format_login_rej(srp_login_req_t *req, srp_login_rej_t *rej,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint32_t reason)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rej->lrej_type = SRP_IU_LOGIN_REJ;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rej->lrej_reason = h2b32(reason);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rej->lrej_tag = req->lreq_tag;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rej->lrej_sup_buf_format =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_format_login_rsp() - Format login response IU
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonstatic void
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_format_login_rsp(srp_login_req_t *req, srp_login_rsp_t *rsp,
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson uint8_t flags)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_type = SRP_IU_LOGIN_RSP;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_req_limit_delta = h2b32((uint32_t)srpt_send_msg_depth);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_tag = req->lreq_tag;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_max_it_iu_len = req->lreq_req_it_iu_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson /* by def. > min T_IU_LEN */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_max_ti_iu_len = req->lreq_req_it_iu_len;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_sup_buf_format =
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rsp->lrsp_rsp_flags = flags;
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_add_task()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_add_task(srpt_session_t *session, srpt_iu_t *iu)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&session->ss_rwlock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_insert_tail(&session->ss_task_list, iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&session->ss_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson/*
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson * srpt_stp_remove_task()
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson */
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonvoid
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleesonsrpt_stp_remove_task(srpt_session_t *session, srpt_iu_t *iu)
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson{
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_enter(&session->ss_rwlock, RW_WRITER);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson ASSERT(!list_is_empty(&session->ss_task_list));
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson list_remove(&session->ss_task_list, iu);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson rw_exit(&session->ss_rwlock);
1bdd6c0e3710e91cb1f31aa78de33cb638494480Sue Gleeson}