450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte/*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * CDDL HEADER START
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * The contents of this file are subject to the terms of the
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Common Development and Distribution License (the "License").
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * You may not use this file except in compliance with the License.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * or http://www.opensolaris.org/os/licensing.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * See the License for the specific language governing permissions
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * and limitations under the License.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If applicable, add the following below this CDDL HEADER, with the
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * CDDL HEADER END
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte/*
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
ef3b9e2fd29bbac9dc0e750d67355287620587a5Dan McDonald * Copyright 2013, Nexenta Systems, Inc. All rights reserved.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/cpuvar.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/types.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/conf.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/file.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/ddi.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/sunddi.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/modctl.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/sysmacros.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/socket.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/strsubr.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/door.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/stmf.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/stmf_ioctl.h>
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte#include <sys/portif.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "pppt.h"
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_tgt_register(stmf_ic_msg_t *reg_port);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_tgt_deregister(stmf_ic_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_session_destroy(stmf_ic_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_scsi_cmd(stmf_ic_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_data_xfer_done(stmf_ic_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void pppt_msg_handle_status(stmf_ic_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortevoid
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_rx(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte switch (msg->icm_msg_type) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_REGISTER_PROXY_PORT:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tgt_register(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_DEREGISTER_PROXY_PORT:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tgt_deregister(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_SESSION_CREATE:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, STMF_NOT_SUPPORTED);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_SESSION_DESTROY:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_session_destroy(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_SCSI_CMD:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_scsi_cmd(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_SCSI_DATA_XFER_DONE:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_data_xfer_done(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_SCSI_DATA:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore, all proxy data will be immediate for now */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, STMF_NOT_SUPPORTED);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte case STMF_ICM_STATUS:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_handle_status(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte default:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Other message types are not allowed */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ASSERT(0);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte break;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortevoid
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_t *msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If TX of status fails it should be treated the same as a loss of
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * connection. We expect the remote node to handle it.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte msg = stmf_ic_status_msg_alloc(status, orig_msg->icm_msg_type,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte orig_msg->icm_msgid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (msg != NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ic_tx_msg(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_tgt_register(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_reg_port_msg_t *reg_port;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_t *result;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status_t stmf_status;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte reg_port = msg->icm_msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_LOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (pppt_global.global_svc_state != PSS_ENABLED) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_FAILURE;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_tgt_reg_svc_disabled);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte goto pppt_register_tgt_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * For now we assume that the marshall/unmarshall code is responsible
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * for validating the message length and ensuring the resulting
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * request structure is self consistent. Make sure this
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * target doesn't already exist.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if ((result = pppt_tgt_lookup_locked(reg_port->icrp_port_id)) != NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_ALREADY;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_tgt_reg_duplicate);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte goto pppt_register_tgt_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte result = pppt_tgt_create(reg_port, &stmf_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (result == NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_TARGET_FAILURE;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_tgt_reg_create_fail);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte goto pppt_register_tgt_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte avl_add(&pppt_global.global_target_list, result);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_SUCCESS;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_register_tgt_done:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, stmf_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_tgt_deregister(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_dereg_port_msg_t *dereg_port;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status_t stmf_status;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_t *tgt;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_LOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (pppt_global.global_svc_state != PSS_ENABLED) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_FAILURE;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_tgt_dereg_svc_disabled);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte goto pppt_deregister_tgt_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte dereg_port = msg->icm_msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Lookup target */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if ((tgt = pppt_tgt_lookup_locked(dereg_port->icdp_port_id)) == NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_NOT_FOUND;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_tgt_dereg_not_found);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte goto pppt_deregister_tgt_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte avl_remove(&pppt_global.global_target_list, tgt);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_async_delete(tgt);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Wait for delete to complete */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_enter(&tgt->target_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte while ((tgt->target_refcount > 0) ||
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (tgt->target_state != TS_DELETING)) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte cv_wait(&tgt->target_cv, &tgt->target_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_exit(&tgt->target_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_destroy(tgt);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status = STMF_SUCCESS;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_deregister_tgt_done:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, stmf_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_session_destroy(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_session_create_destroy_msg_t *sess_destroy;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_t *tgt;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_t *ps;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte sess_destroy = msg->icm_msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_LOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Look for existing session for this ID
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ps = pppt_sess_lookup_locked(sess_destroy->icscd_session_id,
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan sess_destroy->icscd_tgt_devid, sess_destroy->icscd_rport);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ps == NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_sess_destroy_no_session);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt = ps->ps_target;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_enter(&tgt->target_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_enter(&ps->ps_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Release the reference from the lookup */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_rele_locked(ps);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Make sure another thread is not already closing the session */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (!ps->ps_closed) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Found matching open session, quiesce... */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_close_locked(ps);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_exit(&ps->ps_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_exit(&tgt->target_mutex);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_GLOBAL_UNLOCK();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_scsi_cmd(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_t *pppt_sess;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_buf_t *pbuf;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_scsi_cmd_msg_t *scmd;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_task_t *ptask;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scsi_task_t *task;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_status_t pppt_status;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_local_port_t *lport;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_scsi_session_t *stmf_sess;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_status_t stmf_status;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Get a task context
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ptask = pppt_task_alloc();
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ptask == NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We must be very low on memory. Just free the message
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * and let the command timeout.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_scmd_ptask_alloc_fail);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd = msg->icm_msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Session are created implicitly on the first use of an
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * IT nexus
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess = pppt_sess_lookup_create(scmd->icsc_tgt_devid,
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan scmd->icsc_ini_devid, scmd->icsc_rport,
716c180559045549271833327182dc6a266134f1Nattuvetty Bhavyan scmd->icsc_session_id, &stmf_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (pppt_sess == NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_task_free(ptask);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, stmf_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_scmd_sess_create_fail);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ptask->pt_sess = pppt_sess;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ptask->pt_task_id = scmd->icsc_task_msgid;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_sess = pppt_sess->ps_stmf_sess;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte lport = stmf_sess->ss_lport;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Add task to our internal task set.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_status = pppt_task_start(ptask);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (pppt_status != 0) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Release hold from pppt_sess_lookup_create() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_LOG(CE_WARN, "Duplicate taskid from remote node 0x%llx",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (longlong_t)scmd->icsc_task_msgid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_task_free(ptask);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_rele(pppt_sess);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, STMF_ALREADY);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_scmd_dup_task_count);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Allocate STMF task context
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ptask->pt_stmf_task = stmf_task_alloc(lport, stmf_sess,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd->icsc_task_lun_no,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd->icsc_task_cdb_length, 0);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ptask->pt_stmf_task == NULL) {
ef3b9e2fd29bbac9dc0e750d67355287620587a5Dan McDonald /* NOTE: pppt_task_done() will free ptask. */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) pppt_task_done(ptask);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_sess_rele(pppt_sess);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_msg_tx_status(msg, STMF_ALLOC_FAILURE);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte PPPT_INC_STAT(es_scmd_stask_alloc_fail);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task = ptask->pt_stmf_task;
ef3b9e2fd29bbac9dc0e750d67355287620587a5Dan McDonald /* task_port_private reference is a real reference. */
ef3b9e2fd29bbac9dc0e750d67355287620587a5Dan McDonald (void) pppt_task_hold(ptask);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_port_private = ptask;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_flags = scmd->icsc_task_flags;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_additional_flags = 0;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_priority = 0;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Set task->task_mgmt_function to TM_NONE for a normal SCSI task
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * or one of these values for a task management command:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_ABORT_TASK ***
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_ABORT_TASK_SET
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_CLEAR_ACA
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_CLEAR_TASK_SET
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_LUN_RESET
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_TARGET_WARM_RESET
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * TM_TARGET_COLD_RESET
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte *
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * *** Note that STMF does not currently support TM_ABORT_TASK so
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * port providers must implement this command on their own
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * (e.g. lookup the desired task and call stmf_abort).
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_mgmt_function = scmd->icsc_task_mgmt_function;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte task->task_max_nbufs = 1; /* Don't allow parallel xfers */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_cmd_seq_no = msg->icm_msgid;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task->task_expected_xfer_length =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd->icsc_task_expected_xfer_length;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
8f641fa7758451696afe0427885e5b8b75fece49Sue Gleeson if (scmd->icsc_task_cdb_length) {
8f641fa7758451696afe0427885e5b8b75fece49Sue Gleeson bcopy(scmd->icsc_task_cdb, task->task_cdb,
8f641fa7758451696afe0427885e5b8b75fece49Sue Gleeson scmd->icsc_task_cdb_length);
8f641fa7758451696afe0427885e5b8b75fece49Sue Gleeson }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte bcopy(scmd->icsc_lun_id, ptask->pt_lun_id, 16);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (scmd->icsc_immed_data_len) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf = ptask->pt_immed_data;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_immed_msg = msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_stmf_buf->db_data_size = scmd->icsc_immed_data_len;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_stmf_buf->db_buf_size = scmd->icsc_immed_data_len;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_stmf_buf->db_relative_offset = 0;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_stmf_buf->db_sglist[0].seg_length =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd->icsc_immed_data_len;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pbuf->pbuf_stmf_buf->db_sglist[0].seg_addr =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte scmd->icsc_immed_data;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_post_task(task, pbuf->pbuf_stmf_buf);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte } else {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_post_task(task, NULL);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_data_xfer_done(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_task_t *pppt_task;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_scsi_data_xfer_done_msg_t *data_xfer_done;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte data_xfer_done = msg->icm_msg;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /*
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Find task
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_task = pppt_task_lookup(data_xfer_done->icsx_task_msgid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* If we found one, complete the transfer */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (pppt_task != NULL) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_xfer_read_complete(pppt_task, data_xfer_done->icsx_status);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte }
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_msg_handle_status(stmf_ic_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte{
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Don't care for now */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_free(msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte}