fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/modctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/scsi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/impl/scsi_reset_notify.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/disp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/byteorder.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/varargs.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/atomic.h>
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer#include <sys/sdt.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf_ioctl.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/portif.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/fct.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/fctio.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "fct_impl.h"
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "discovery.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void **result);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_open(dev_t *devp, int flag, int otype, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_close(dev_t dev, int flag, int otype, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred_t *credp, int *rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fct_fctiocmd(intptr_t data, int mode);
c946faca5d4627284fb79c6b04e652b471034495allanvoid fct_init_kstats(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dev_info_t *fct_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct cb_ops fct_cb_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_open, /* open */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_close, /* close */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* strategy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* print */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* dump */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* read */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* write */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_ioctl, /* ioctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* devmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* mmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* segmap */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nochpoll, /* chpoll */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_op, /* cb_prop_op */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* streamtab */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte D_NEW | D_MP, /* cb_flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_REV, /* rev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* aread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev /* awrite */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct dev_ops fct_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DEVO_REV,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_getinfo,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* identify */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nulldev, /* probe */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_attach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_detach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* reset */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fct_cb_ops,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_ops */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL /* power */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCT_NAME "COMSTAR FCT"
c946faca5d4627284fb79c6b04e652b471034495allan#define FCT_MODULE_NAME "fct"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern struct mod_ops mod_driverops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modldrv modldrv = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mod_driverops,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_NAME,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fct_ops
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlinkage modlinkage = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODREV_1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modldrv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t rportid_table_size = FCT_HASH_TABLE_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int max_cached_ncmds = FCT_MAX_CACHED_CMDS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fct_i_local_port_t *fct_iport_list = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t fct_global_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint32_t fct_rscn_options = RSCN_OPTION_VERIFY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_init(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mod_install(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fct_global_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_fini(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mod_remove(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_info(struct modinfo *modinfop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mod_info(&modlinkage, modinfop));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2DEVINFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = fct_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2INSTANCE:
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto *result = (void *)(uintptr_t)ddi_get_instance(fct_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dip = dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "admin", S_IFCHR, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_NT_STMF_PP, 0) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_report_dev(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(dip, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_open(dev_t *devp, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otype != OTYP_CHR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_close(dev_t dev, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cred_t *credp, int *rval)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd & 0xff000000) != FCT_IOCTL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOTTY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (drv_priv(credp) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EPERM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_CMD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_fctiocmd(data, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ENOTTY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_copyin_iocdata(intptr_t data, int mode, fctio_t **fctio,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void **ibuf, void **abuf, void **obuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ibuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *abuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *obuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *fctio = kmem_zalloc(sizeof (fctio_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)data, *fctio, sizeof (fctio_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto copyin_iocdata_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*fctio)->fctio_ilen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ibuf = kmem_zalloc((*fctio)->fctio_ilen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(unsigned long)(*fctio)->fctio_ibuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ibuf, (*fctio)->fctio_ilen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto copyin_iocdata_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*fctio)->fctio_alen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *abuf = kmem_zalloc((*fctio)->fctio_alen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(unsigned long)(*fctio)->fctio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *abuf, (*fctio)->fctio_alen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto copyin_iocdata_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*fctio)->fctio_olen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *obuf = kmem_zalloc((*fctio)->fctio_olen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecopyin_iocdata_done:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*obuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(*obuf, (*fctio)->fctio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *obuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*abuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(*abuf, (*fctio)->fctio_alen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *abuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*ibuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(*ibuf, (*fctio)->fctio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ibuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(*fctio, sizeof (fctio_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_copyout_iocdata(intptr_t data, int mode, fctio_t *fctio, void *obuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyout(obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)(unsigned long)fctio->fctio_obuf, fctio->fctio_olen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyout(fctio, (void *)data, sizeof (fctio_t), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_port_list(char *pathList, int count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i = 0, maxPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pathList != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iport = fct_iport_list; iport; iport = iport->iport_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i < count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pathList + 8 * i, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maxPorts ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (maxPorts);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* invoked with fct_global_mutex locked */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_i_local_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_iport_per_wwn(uint8_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&fct_global_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iport = fct_iport_list; iport; iport = iport->iport_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(iport->iport_port->port_pwwn, pwwn, 8) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_adapter_attr(uint8_t *pwwn, fc_tgt_hba_adapter_attributes_t *hba_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *err_detail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_port_attrs_t *attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba_attr->version = FCT_HBA_ADAPTER_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = fct_get_iport_per_wwn(pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *err_detail = FCTIO_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr = (fct_port_attrs_t *)kmem_zalloc(sizeof (fct_port_attrs_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_port->port_populate_hba_details(iport->iport_port, attr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->manufacturer, hba_attr->Manufacturer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->Manufacturer));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->serial_number, hba_attr->SerialNumber,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->SerialNumber));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->model, hba_attr->Model, sizeof (hba_attr->Model));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->model_description, hba_attr->ModelDescription,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->ModelDescription));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_port->port_sym_node_name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_sym_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba_attr->NodeSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(iport->iport_port->port_sym_node_name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(utsname.nodename, hba_attr->NodeSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(utsname.nodename));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->hardware_version, hba_attr->HardwareVersion,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->HardwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->option_rom_version, hba_attr->OptionROMVersion,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->OptionROMVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->firmware_version, hba_attr->FirmwareVersion,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->FirmwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba_attr->VendorSpecificID = attr->vendor_specific_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_nwwn, hba_attr->NodeWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->NodeWWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->driver_name, hba_attr->DriverName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->DriverName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(attr->driver_version, hba_attr->DriverVersion,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (hba_attr->DriverVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* hba_attr->NumberOfPorts = fct_count_fru_ports(iport); */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba_attr->NumberOfPorts = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(attr, sizeof (fct_port_attrs_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_adapter_port_attr(fct_i_local_port_t *ilport, uint8_t *pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_port_attributes_t *port_attr, uint32_t *err_detail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ilport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_port_attrs_t *attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->version = FCT_HBA_PORT_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ilport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = fct_get_iport_per_wwn(pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *err_detail = FCTIO_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr = (fct_port_attrs_t *)kmem_zalloc(sizeof (fct_port_attrs_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_port->port_populate_hba_details(iport->iport_port, attr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->lastChange = iport->iport_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_nwwn, port_attr->NodeWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port_attr->NodeWWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_pwwn, port_attr->PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port_attr->PortWWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(port_attr->FabricName, sizeof (port_attr->FabricName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortFcId = iport->iport_link_info.portid;
e90983c88d2892da50e700f57b6b2d5613557077allan if ((iport->iport_link_state & S_LINK_ONLINE) ||
e90983c88d2892da50e700f57b6b2d5613557077allan (iport->iport_link_state & S_RCVD_LINK_UP)) {
e90983c88d2892da50e700f57b6b2d5613557077allan port_attr->PortState = FC_HBA_PORTSTATE_ONLINE;
e90983c88d2892da50e700f57b6b2d5613557077allan } else {
e90983c88d2892da50e700f57b6b2d5613557077allan port_attr->PortState = FC_HBA_PORTSTATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (iport->iport_link_info.port_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_TOPOLOGY_PT_TO_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_PTP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_TOPOLOGY_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_LPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_TOPOLOGY_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_NLPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_TOPOLOGY_FABRIC_PT_TO_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_FPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedClassofService = attr->supported_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedFc4Types[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortActiveFc4Types[2] = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_port->port_sym_port_name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_sym_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(iport->iport_port->port_sym_port_name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (iport->iport_port->port_default_alias)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_default_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(iport->iport_port->port_default_alias));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSymbolicName[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* the definition is different so need to translate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr->supported_speed & PORT_SPEED_1G)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_1GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr->supported_speed & PORT_SPEED_2G)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_2GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr->supported_speed & PORT_SPEED_4G)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_4GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr->supported_speed & PORT_SPEED_8G)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_8GBIT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang if (attr->supported_speed & PORT_SPEED_10G)
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_10GBIT;
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen if (attr->supported_speed & PORT_SPEED_16G)
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen port_attr->PortSupportedSpeed |= FC_HBA_PORTSPEED_16GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (iport->iport_link_info.port_speed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_SPEED_1G:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_1GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_SPEED_2G:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_2GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_SPEED_4G:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_4GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case PORT_SPEED_8G:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_8GBIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang case PORT_SPEED_10G:
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang port_attr->PortSpeed = FC_HBA_PORTSPEED_10GBIT;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang break;
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen case PORT_SPEED_16G:
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen port_attr->PortSpeed = FC_HBA_PORTSPEED_16GBIT;
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortMaxFrameSize = attr->max_frame_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->NumberofDiscoveredPorts = iport->iport_nrps_login;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; i < iport->iport_port->port_max_logins; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_slots[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp && irp->irp_flags & IRP_PLOGI_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_WELL_KNOWN_ADDR(irp->irp_portid))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->NumberofDiscoveredPorts --;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(attr, sizeof (fct_port_attrs_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_discovered_port_attr(fct_i_remote_port_t *remote_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn, uint32_t index, fc_tgt_hba_port_attributes_t *port_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *error_detail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = remote_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count = 0, i = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->version = FCT_HBA_PORT_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!remote_port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = fct_get_iport_per_wwn(port_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_detail = FCTIO_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index >= iport->iport_nrps_login) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_detail = FCTIO_OUTOFBOUNDS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; i < iport->iport_port->port_max_logins; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_slots[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp && irp->irp_flags & IRP_PLOGI_DONE &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !FC_WELL_KNOWN_ADDR(irp->irp_portid)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((index + 1) <= count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i >= iport->iport_port->port_max_logins) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_detail = FCTIO_OUTOFBOUNDS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_rp->rp_port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->lastChange = iport->iport_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(irp->irp_rp->rp_pwwn, port_attr->PortWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port_attr->PortWWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(irp->irp_rp->rp_nwwn, port_attr->NodeWWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port_attr->NodeWWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortFcId = irp->irp_portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_spn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(port_attr->PortSymbolicName, irp->irp_spn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(irp->irp_spn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSymbolicName[0] = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedClassofService = irp->irp_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)irp->irp_fc4types, port_attr->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (irp->irp_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)irp->irp_fc4types, port_attr->PortSupportedFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (irp->irp_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_PLOGI_DONE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortState = FC_HBA_PORTSTATE_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortState = FC_HBA_PORTSTATE_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortType = FC_HBA_PORTTYPE_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSupportedSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->PortMaxFrameSize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr->NumberofDiscoveredPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!remote_port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_port_attr(uint8_t *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_port_attributes_t *port_attr, uint32_t *error_detail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = fct_get_iport_per_wwn(port_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fct_get_adapter_port_attr(iport, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr, error_detail));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (iport = fct_iport_list; iport; iport = iport->iport_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < rportid_table_size; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_tb[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(irp->irp_rp->rp_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_wwn, 8) == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_flags & IRP_PLOGI_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_discovered_port_attr(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp, NULL, 0, port_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error_detail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_detail = FCTIO_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_port_stats(uint8_t *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_adapter_port_stats_t *port_stats, uint32_t *error_detail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
c946faca5d4627284fb79c6b04e652b471034495allan int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = fct_get_iport_per_wwn(port_wwn);
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_link_status_t stat;
c946faca5d4627284fb79c6b04e652b471034495allan uint32_t buf_size = sizeof (fc_tgt_hba_adapter_port_stats_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_stats->version = FCT_HBA_ADAPTER_PORT_STATS_VERSION;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_port->port_info == NULL) {
c946faca5d4627284fb79c6b04e652b471034495allan *error_detail = FCTIO_FAILURE;
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan ret = iport->iport_port->port_info(FC_TGT_PORT_RLS,
c946faca5d4627284fb79c6b04e652b471034495allan iport->iport_port, NULL, (uint8_t *)&stat, &buf_size);
c946faca5d4627284fb79c6b04e652b471034495allan if (ret != STMF_SUCCESS) {
c946faca5d4627284fb79c6b04e652b471034495allan *error_detail = FCTIO_FAILURE;
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->SecondsSinceLastReset = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->TxFrames = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->TxWords = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->RxFrames = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->RxWords = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->LIPCount = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->NOSCount = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->ErrorFrames = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->DumpedFrames = 0;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->LinkFailureCount = stat.LinkFailureCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->LossOfSyncCount = stat.LossOfSyncCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->LossOfSignalCount = stat.LossOfSignalsCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->PrimitiveSeqProtocolErrCount =
c946faca5d4627284fb79c6b04e652b471034495allan stat.PrimitiveSeqProtocolErrorCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->InvalidTxWordCount =
c946faca5d4627284fb79c6b04e652b471034495allan stat.InvalidTransmissionWordCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_stats->InvalidCRCCount = stat.InvalidCRCCount;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan return (ret);
c946faca5d4627284fb79c6b04e652b471034495allan}
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allanint
c946faca5d4627284fb79c6b04e652b471034495allanfct_get_link_status(uint8_t *port_wwn, uint64_t *dest_id,
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_link_status_t *link_status, uint32_t *error_detail)
c946faca5d4627284fb79c6b04e652b471034495allan{
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_local_port_t *iport = fct_get_iport_per_wwn(port_wwn);
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_remote_port_t *irp = NULL;
c946faca5d4627284fb79c6b04e652b471034495allan uint32_t buf_size = sizeof (fct_port_link_status_t);
c946faca5d4627284fb79c6b04e652b471034495allan stmf_status_t ret = 0;
c946faca5d4627284fb79c6b04e652b471034495allan int i;
c946faca5d4627284fb79c6b04e652b471034495allan fct_cmd_t *cmd = NULL;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (!iport) {
c946faca5d4627284fb79c6b04e652b471034495allan *error_detail = FCTIO_BADWWN;
c946faca5d4627284fb79c6b04e652b471034495allan return (ENXIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
c946faca5d4627284fb79c6b04e652b471034495allan * If what we are requesting is zero or same as local port,
c946faca5d4627284fb79c6b04e652b471034495allan * then we use port_info()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
c946faca5d4627284fb79c6b04e652b471034495allan if (dest_id == NULL || *dest_id == iport->iport_link_info.portid) {
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_port->port_info == NULL) {
c946faca5d4627284fb79c6b04e652b471034495allan *error_detail = FCTIO_FAILURE;
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan ret = iport->iport_port->port_info(FC_TGT_PORT_RLS,
c946faca5d4627284fb79c6b04e652b471034495allan iport->iport_port, NULL,
c946faca5d4627284fb79c6b04e652b471034495allan (uint8_t *)link_status, &buf_size);
c946faca5d4627284fb79c6b04e652b471034495allan if (ret == STMF_SUCCESS) {
c946faca5d4627284fb79c6b04e652b471034495allan return (0);
c946faca5d4627284fb79c6b04e652b471034495allan } else {
c946faca5d4627284fb79c6b04e652b471034495allan *error_detail = FCTIO_FAILURE;
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan /*
c946faca5d4627284fb79c6b04e652b471034495allan * For remote port, we will send RLS
c946faca5d4627284fb79c6b04e652b471034495allan */
c946faca5d4627284fb79c6b04e652b471034495allan for (i = 0; i < rportid_table_size; i++) {
c946faca5d4627284fb79c6b04e652b471034495allan irp = iport->iport_rp_tb[i];
c946faca5d4627284fb79c6b04e652b471034495allan while (irp) {
c946faca5d4627284fb79c6b04e652b471034495allan if (irp->irp_rp->rp_id == *dest_id &&
c946faca5d4627284fb79c6b04e652b471034495allan irp->irp_flags & IRP_PLOGI_DONE) {
c946faca5d4627284fb79c6b04e652b471034495allan goto SEND_RLS_ELS;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan irp = irp->irp_next;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan return (ENXIO);
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allanSEND_RLS_ELS:
c946faca5d4627284fb79c6b04e652b471034495allan cmd = fct_create_solels(iport->iport_port,
c946faca5d4627284fb79c6b04e652b471034495allan irp->irp_rp, 0, ELS_OP_RLS,
c946faca5d4627284fb79c6b04e652b471034495allan 0, fct_rls_cb);
c946faca5d4627284fb79c6b04e652b471034495allan if (!cmd)
c946faca5d4627284fb79c6b04e652b471034495allan return (ENOMEM);
c946faca5d4627284fb79c6b04e652b471034495allan iport->iport_rls_cb_data.fct_link_status = link_status;
c946faca5d4627284fb79c6b04e652b471034495allan CMD_TO_ICMD(cmd)->icmd_cb_private = &iport->iport_rls_cb_data;
c946faca5d4627284fb79c6b04e652b471034495allan fct_post_to_solcmd_queue(iport->iport_port, cmd);
c946faca5d4627284fb79c6b04e652b471034495allan sema_p(&iport->iport_rls_sema);
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_rls_cb_data.fct_els_res != FCT_SUCCESS)
c946faca5d4627284fb79c6b04e652b471034495allan ret = EIO;
c946faca5d4627284fb79c6b04e652b471034495allan return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
a79493184c9332129c9c91500069322f6f3fafddReedstatic int
a79493184c9332129c9c91500069322f6f3fafddReedfct_forcelip(uint8_t *port_wwn, uint32_t *fctio_errno)
a79493184c9332129c9c91500069322f6f3fafddReed{
a79493184c9332129c9c91500069322f6f3fafddReed fct_status_t rval;
a79493184c9332129c9c91500069322f6f3fafddReed fct_i_local_port_t *iport;
a79493184c9332129c9c91500069322f6f3fafddReed
a79493184c9332129c9c91500069322f6f3fafddReed mutex_enter(&fct_global_mutex);
a79493184c9332129c9c91500069322f6f3fafddReed iport = fct_get_iport_per_wwn(port_wwn);
a79493184c9332129c9c91500069322f6f3fafddReed mutex_exit(&fct_global_mutex);
a79493184c9332129c9c91500069322f6f3fafddReed if (iport == NULL) {
a79493184c9332129c9c91500069322f6f3fafddReed return (-1);
a79493184c9332129c9c91500069322f6f3fafddReed }
a79493184c9332129c9c91500069322f6f3fafddReed
a79493184c9332129c9c91500069322f6f3fafddReed iport->iport_port->port_ctl(iport->iport_port,
a79493184c9332129c9c91500069322f6f3fafddReed FCT_CMD_FORCE_LIP, &rval);
a79493184c9332129c9c91500069322f6f3fafddReed if (rval != FCT_SUCCESS) {
a79493184c9332129c9c91500069322f6f3fafddReed *fctio_errno = FCTIO_FAILURE;
a79493184c9332129c9c91500069322f6f3fafddReed } else {
a79493184c9332129c9c91500069322f6f3fafddReed *fctio_errno = 0;
a79493184c9332129c9c91500069322f6f3fafddReed }
a79493184c9332129c9c91500069322f6f3fafddReed
a79493184c9332129c9c91500069322f6f3fafddReed return (0);
a79493184c9332129c9c91500069322f6f3fafddReed}
a79493184c9332129c9c91500069322f6f3fafddReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_fctiocmd(intptr_t data, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *ibuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *obuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *abuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio_t *fctio;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t attr_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_copyin_iocdata(data, mode, &fctio, &ibuf, &abuf, &obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (fctio->fctio_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_ADAPTER_LIST: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_list_t *list = (fc_tgt_hba_list_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen < sizeof (fc_tgt_hba_list_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->numPorts = (fctio->fctio_olen -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_tgt_hba_list_t))/8 + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->version = FCT_HBA_LIST_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = fct_get_port_list((char *)list->port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->numPorts);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count > list->numPorts) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio->fctio_errno = FCTIO_MOREDATA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ENOSPC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->numPorts = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_GET_ADAPTER_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_adapter_attributes_t *hba_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn = (uint8_t *)ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr_length = sizeof (fc_tgt_hba_adapter_attributes_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen < attr_length ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio->fctio_xfer != FCTIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba_attr = (fc_tgt_hba_adapter_attributes_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_adapter_attr(port_wwn, hba_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fctio->fctio_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_GET_ADAPTER_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_port_attributes_t *port_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn = (uint8_t *)ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr_length = sizeof (fc_tgt_hba_port_attributes_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen < attr_length ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio->fctio_xfer != FCTIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr = (fc_tgt_hba_port_attributes_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_adapter_port_attr(NULL, port_wwn, port_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fctio->fctio_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_GET_DISCOVERED_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn = (uint8_t *)ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *port_index = (uint32_t *)abuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_port_attributes_t *port_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr_length = sizeof (fc_tgt_hba_port_attributes_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen < attr_length ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio->fctio_xfer != FCTIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr = (fc_tgt_hba_port_attributes_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_discovered_port_attr(NULL, port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *port_index, port_attr, &fctio->fctio_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_GET_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn = (uint8_t *)ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_port_attributes_t *port_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr_length = sizeof (fc_tgt_hba_port_attributes_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctio->fctio_olen < attr_length ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctio->fctio_xfer != FCTIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_attr = (fc_tgt_hba_port_attributes_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_port_attr(port_wwn, port_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fctio->fctio_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCTIO_GET_ADAPTER_PORT_STATS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *port_wwn = (uint8_t *)ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_tgt_hba_adapter_port_stats_t *port_stats =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_tgt_hba_adapter_port_stats_t *)obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_get_port_stats(port_wwn, port_stats,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fctio->fctio_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
c946faca5d4627284fb79c6b04e652b471034495allan case FCTIO_GET_LINK_STATUS: {
c946faca5d4627284fb79c6b04e652b471034495allan uint8_t *port_wwn = (uint8_t *)ibuf;
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_link_status_t *link_status =
c946faca5d4627284fb79c6b04e652b471034495allan (fct_port_link_status_t *)obuf;
c946faca5d4627284fb79c6b04e652b471034495allan uint64_t *dest_id = abuf;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan mutex_enter(&fct_global_mutex);
c946faca5d4627284fb79c6b04e652b471034495allan ret = fct_get_link_status(port_wwn, dest_id, link_status,
c946faca5d4627284fb79c6b04e652b471034495allan &fctio->fctio_errno);
c946faca5d4627284fb79c6b04e652b471034495allan mutex_exit(&fct_global_mutex);
c946faca5d4627284fb79c6b04e652b471034495allan break;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
a79493184c9332129c9c91500069322f6f3fafddReed case FCTIO_FORCE_LIP:
a79493184c9332129c9c91500069322f6f3fafddReed ret = fct_forcelip((uint8_t *)ibuf, &fctio->fctio_errno);
a79493184c9332129c9c91500069322f6f3fafddReed break;
a79493184c9332129c9c91500069322f6f3fafddReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_copyout_iocdata(data, mode, fctio, obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fctio->fctio_errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_copyout_iocdata(data, mode, fctio, obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (obuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(obuf, fctio->fctio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte obuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (abuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(abuf, fctio->fctio_alen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte abuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ibuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ibuf, fctio->fctio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ibuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fctio, sizeof (fctio_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *bp; /* back pointer from internal struct to main struct */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int alloc_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_struct_id_t struct_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} __ifct_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte __ifct_t *fp; /* Framework private */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *cp; /* Caller private */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *ss; /* struct specific */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} __fct_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int shared;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fw_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int struct_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} fct_sizes[] = { { 0, 0, 0 },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_local_port_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_local_port_t), 0 },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_remote_port_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_remote_port_t), 0 },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_cmd_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_cmd_t), GET_STRUCT_SIZE(fct_els_t) },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_cmd_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_cmd_t), GET_STRUCT_SIZE(fct_els_t) },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_cmd_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_cmd_t), GET_STRUCT_SIZE(fct_sol_ct_t) },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_cmd_t), GET_STRUCT_SIZE(fct_i_cmd_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_rcvd_abts_t) },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_cmd_t), /* FCT_STRUCT_CMD_FCP_XCHG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(fct_i_cmd_t), 0 },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { GET_STRUCT_SIZE(fct_dbuf_store_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GET_STRUCT_SIZE(__ifct_t), 0 }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_alloc(fct_struct_id_t struct_id, int additional_size, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fct_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int kmem_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte __fct_t *sh;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((struct_id == 0) || (struct_id >= FCT_MAX_STRUCT_IDS))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((curthread->t_flag & T_INTR_THREAD) || (flags & AF_FORCE_NOSLEEP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_flag = KM_NOSLEEP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_flag = KM_SLEEP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte additional_size = (additional_size + 7) & (~7);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_size = fct_sizes[struct_id].shared +
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_sizes[struct_id].fw_private +
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_sizes[struct_id].struct_specific + additional_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (struct_id == FCT_STRUCT_LOCAL_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_local_port_t *lport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport = (stmf_local_port_t *)stmf_alloc(
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer STMF_STRUCT_STMF_LOCAL_PORT, fct_size, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh = (__fct_t *)lport->lport_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->ss = lport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_DBUF_STORE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_dbuf_store_t *ds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ds = (stmf_dbuf_store_t *)stmf_alloc(STMF_STRUCT_DBUF_STORE,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_size, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh = (__fct_t *)ds->ds_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->ss = ds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh = (__fct_t *)kmem_zalloc(fct_size, kmem_flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sh == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->fp = (__ifct_t *)GET_BYTE_OFFSET(sh, fct_sizes[struct_id].shared);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->cp = GET_BYTE_OFFSET(sh->fp, fct_sizes[struct_id].fw_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_sizes[struct_id].struct_specific)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->ss = GET_BYTE_OFFSET(sh->cp, additional_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->fp->bp = sh;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->fp->alloc_size = fct_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sh->fp->struct_id = struct_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (struct_id == FCT_STRUCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)sh)->cmd_type = FCT_CMD_FCP_XCHG;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)sh)->cmd_type = FCT_CMD_RCVD_ELS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)sh)->cmd_type = FCT_CMD_SOL_ELS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_CMD_RCVD_ABTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)sh)->cmd_type = FCT_CMD_RCVD_ABTS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_CMD_SOL_CT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)sh)->cmd_type = FCT_CMD_SOL_CT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sh);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_free(void *ptr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte __fct_t *sh = (__fct_t *)ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_struct_id_t struct_id = sh->fp->struct_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (struct_id == FCT_STRUCT_CMD_SOL_CT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = (fct_sol_ct_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)ptr)->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct->ct_req_alloc_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ct->ct_req_payload, ct->ct_req_alloc_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct->ct_resp_alloc_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ct->ct_resp_payload, ct->ct_resp_alloc_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((struct_id == FCT_STRUCT_CMD_RCVD_ELS) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (struct_id == FCT_STRUCT_CMD_SOL_ELS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fct_cmd_t *)ptr)->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (els->els_req_alloc_size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(els->els_req_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_alloc_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (els->els_resp_alloc_size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(els->els_resp_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (struct_id == FCT_STRUCT_LOCAL_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(((fct_local_port_t *)ptr)->port_lport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (struct_id == FCT_STRUCT_DBUF_STORE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(((fct_dbuf_store_t *)ptr)->fds_ds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ptr, sh->fp->alloc_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_data_buf_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_alloc_dbuf(scsi_task_t *task, uint32_t size, uint32_t *pminsize,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = (fct_local_port_t *)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer task->task_lport->lport_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->port_fds->fds_alloc_data_buf(port, size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pminsize, flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorestmf_status_t
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorefct_setup_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t flags)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore{
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore fct_local_port_t *port = (fct_local_port_t *)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_lport->lport_port_private;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ASSERT(port->port_fds->fds_setup_dbuf != NULL);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore if (port->port_fds->fds_setup_dbuf == NULL)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore return (STMF_FAILURE);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore return (port->port_fds->fds_setup_dbuf(port, dbuf, flags));
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore}
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorevoid
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorefct_teardown_dbuf(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore{
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore fct_dbuf_store_t *fds = ds->ds_port_private;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore fds->fds_teardown_dbuf(fds, dbuf);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore}
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_free_dbuf(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dbuf_store_t *fds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fds = (fct_dbuf_store_t *)ds->ds_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fds->fds_free_data_buf(fds, dbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t taskq_cntr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_register_local_port(fct_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_local_port_t *lport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_slot_t *slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char taskq_name[FCT_TASKQ_NAME_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)port->port_fct_private;
162fafd3d0764eb6022fe01ce970de8775eda209allan if (port->port_fca_version != FCT_FCA_MODREV_1) {
162fafd3d0764eb6022fe01ce970de8775eda209allan cmn_err(CE_WARN,
162fafd3d0764eb6022fe01ce970de8775eda209allan "fct: %s driver version mismatch",
162fafd3d0764eb6022fe01ce970de8775eda209allan port->port_default_alias);
162fafd3d0764eb6022fe01ce970de8775eda209allan return (FCT_FAILURE);
162fafd3d0764eb6022fe01ce970de8775eda209allan }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->port_default_alias) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int l = strlen(port->port_default_alias);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (l < 16) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_alias = iport->iport_alias_mem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_alias =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (char *)kmem_zalloc(l+1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(iport->iport_alias, port->port_default_alias);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_alias = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_wwn_to_devid_desc((scsi_devid_desc_t *)iport->iport_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_pwwn, PROTOCOL_FIBRE_CHANNEL);
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(taskq_name, sizeof (taskq_name), "stmf_fct_taskq_%d",
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32_nv(&taskq_cntr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_worker_taskq = ddi_taskq_create(NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_name, 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&iport->iport_worker_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&iport->iport_worker_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&iport->iport_lock, NULL, RW_DRIVER, NULL);
c946faca5d4627284fb79c6b04e652b471034495allan sema_init(&iport->iport_rls_sema, 0, NULL, SEMA_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Remote port mgmt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_slots = (fct_i_remote_port_t **)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_max_logins * sizeof (fct_i_remote_port_t *), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_tb = kmem_zalloc(rportid_table_size *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fct_cmds for SCSI traffic */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_total_alloced_ncmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_ncmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fca_fcp_cmd_size =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (port->port_fca_fcp_cmd_size + 7) & ~7;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_cmdlist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&iport->iport_cached_cmd_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Initialize cmd slots */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cmd_slots = (fct_cmd_slot_t *)kmem_zalloc(
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer port->port_max_xchges * sizeof (fct_cmd_slot_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_next_free_slot = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < port->port_max_xchges; ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot = &iport->iport_cmd_slots[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_no = (uint16_t)i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_next = (uint16_t)(++i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_next = FCT_SLOT_EOL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_nslots_free = port->port_max_xchges;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_task_green_limit =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (port->port_max_xchges * FCT_TASK_GREEN_LIMIT) / 100;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_task_yellow_limit =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (port->port_max_xchges * FCT_TASK_YELLOW_LIMIT) / 100;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_task_red_limit =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (port->port_max_xchges * FCT_TASK_RED_LIMIT) / 100;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start worker thread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags, ~IPORT_TERMINATE_WORKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_taskq_dispatch(iport->iport_worker_taskq,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_port_worker, port, DDI_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for taskq to start */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((iport->iport_flags & IPORT_WORKER_RUNNING) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport = port->port_lport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_id = (scsi_devid_desc_t *)iport->iport_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_alias = iport->iport_alias;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_pp = port->port_pp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fds->fds_ds->ds_alloc_data_buf = fct_alloc_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fds->fds_ds->ds_free_data_buf = fct_free_dbuf;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore port->port_fds->fds_ds->ds_setup_dbuf = fct_setup_dbuf;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore port->port_fds->fds_ds->ds_teardown_dbuf = fct_teardown_dbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_ds = port->port_fds->fds_ds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_xfer_data = fct_xfer_scsi_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_send_status = fct_send_scsi_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_task_free = fct_scsi_task_free;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_abort = fct_scsi_abort;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_ctl = fct_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_info = fct_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_event_handler = fct_event_handler;
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte /* set up as alua participating port */
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte stmf_set_port_alua(lport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_register_local_port(port->port_lport) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fct_regport_fail1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_lport_add_event(lport, LPORT_EVENT_INITIAL_LUN_MAPPED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_next = fct_iport_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_next->iport_prev = iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_iport_list = iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c946faca5d4627284fb79c6b04e652b471034495allan fct_init_kstats(iport);
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_local_port_event(port, ESC_SUNFC_PORT_ATTACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_regport_fail1:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Stop the taskq 1st */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_flags & IPORT_WORKER_RUNNING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags, IPORT_TERMINATE_WORKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (iport->iport_flags & IPORT_WORKER_RUNNING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_taskq_destroy(iport->iport_worker_taskq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rp_tb) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(iport->iport_rp_tb, rportid_table_size *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_deregister_local_port(fct_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd, *next_icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ndx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_state != FCT_STATE_OFFLINE) ||
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer iport->iport_state_not_acked) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Stop the taskq 1st */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_flags & IPORT_WORKER_RUNNING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags, IPORT_TERMINATE_WORKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ndx = 0; ndx < 100; ndx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_flags & IPORT_WORKER_RUNNING)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(10000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ndx == 100) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ~IPORT_TERMINATE_WORKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_WORKER_STUCK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_deregister_local_port(port->port_lport) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fct_deregport_fail1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_next->iport_prev = iport->iport_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_prev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_prev->iport_next = iport->iport_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_iport_list = iport->iport_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fct_global_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this time, there should be no outstanding and pending
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * I/Os, so we can just release resources.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_total_alloced_ncmds == iport->iport_cached_ncmds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (icmd = iport->iport_cached_cmdlist; icmd; icmd = next_icmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_icmd = icmd->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(icmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(iport->iport_cmd_slots, port->port_max_xchges *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_cmd_slot_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(iport->iport_rp_slots, port->port_max_logins *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&iport->iport_worker_cv);
c946faca5d4627284fb79c6b04e652b471034495allan sema_destroy(&iport->iport_rls_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_taskq_destroy(iport->iport_worker_taskq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rp_tb) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(iport->iport_rp_tb, rportid_table_size *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_kstat_portstat) {
c946faca5d4627284fb79c6b04e652b471034495allan kstat_delete(iport->iport_kstat_portstat);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_local_port_event(port, ESC_SUNFC_PORT_DETACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_deregport_fail1:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Restart the worker */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags, ~IPORT_TERMINATE_WORKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_taskq_dispatch(iport->iport_worker_taskq,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_port_worker, port, DDI_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for taskq to start */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((iport->iport_flags & IPORT_WORKER_RUNNING) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_event(fct_local_port_t *port, int event_id, uint32_t event_flags,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen caddr_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_event_t *e;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte e = kmem_zalloc(sizeof (fct_i_event_t), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (e == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX Throw HBA fatal error event
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_handle_event: iport-%p, allocation "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "of fct_i_event failed", (void *)iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just queue the event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte e->event_type = event_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_event_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_event_head = iport->iport_event_tail = e;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_event_tail->event_next = e;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_event_tail = e;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_WORKER_SLEEPING(iport))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with iport_lock held as reader.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_i_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_portid_to_portptr(fct_i_local_port_t *iport, uint32_t portid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_tb[FCT_PORTID_HASH_FUNC(portid)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; irp != NULL; irp = irp->irp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_portid == portid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with irp_lock held as writer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_queue_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_key =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_PORTID_HASH_FUNC(irp->irp_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_next = iport->iport_rp_tb[hash_key];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_tb[hash_key] = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_nrps++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with irp_lock and iport_lock held as writer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_deque_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hash_key =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_PORTID_HASH_FUNC(irp->irp_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_next = iport->iport_rp_tb[hash_key];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp_next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == irp_next) {
acb5a994969e54d1b7de2f636cae6a19169bb0f2Yu Renia Miao if (irp->irp_flags & IRP_PLOGI_DONE) {
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&iport->iport_nrps_login);
acb5a994969e54d1b7de2f636cae6a19169bb0f2Yu Renia Miao }
acb5a994969e54d1b7de2f636cae6a19169bb0f2Yu Renia Miao atomic_and_32(&irp->irp_flags,
acb5a994969e54d1b7de2f636cae6a19169bb0f2Yu Renia Miao ~(IRP_PLOGI_DONE | IRP_PRLI_DONE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_last = irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_next = irp_next->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp_last == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_tb[hash_key] =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_last->irp_next = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_nrps--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_is_irp_logging_out(fct_i_remote_port_t *irp, int force_implicit)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int logging_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_IN_DISCOVERY_QUEUE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto ilo_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_els_list == NULL) && (irp->irp_deregister_timer)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (force_implicit && irp->irp_nonfcp_xchg_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto ilo_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_els_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Last session affecting ELS should be a LOGO */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (icmd = irp->irp_els_list; icmd; icmd = icmd->icmd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op = (ICMD_TO_ELS(icmd))->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (op == ELS_OP_LOGO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (force_implicit) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_IMPLICIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((op == ELS_OP_PLOGI) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (op == ELS_OP_PRLI) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (op == ELS_OP_PRLO) || (op == ELS_OP_TPRLO)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logging_out = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteilo_done:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (logging_out);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The force_implicit flag enforces the implicit semantics which may be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * needed if a received logout got stuck e.g. a response to a received
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LOGO never came back from the FCA.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_implicitly_logo_all(fct_i_local_port_t *iport, int force_implicit)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nports = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport->iport_nrps) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (nports);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < rportid_table_size; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_tb[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!(irp->irp_flags & IRP_PLOGI_DONE)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fct_is_irp_logging_out(irp, force_implicit))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fct_create_solels(iport->iport_port, irp->irp_rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, ELS_OP_LOGO, 0, fct_logo_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_implictly_logo_all: cmd null");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (nports);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_implicit_logo(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nports++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (nports);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_rehash(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t **iport_rp_tb_tmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t **iport_rp_tb_new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport_rp_tb_new = kmem_zalloc(rportid_table_size *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* reconstruct the hash table */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport_rp_tb_tmp = iport->iport_rp_tb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_tb = iport_rp_tb_new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_nrps = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < rportid_table_size; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport_rp_tb_tmp[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_next = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_rp(iport, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(iport_rp_tb_tmp, rportid_table_size *
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer sizeof (fct_i_remote_port_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint8_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_local_port_cleanup_done(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_nrps_login)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* loop all rps to check if the cmd have already been drained */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < rportid_table_size; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_tb[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_fcp_xchg_count ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_nonfcp_xchg_count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_scsi_task_alloc(fct_local_port_t *port, uint16_t rp_handle,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen uint32_t rportid, uint8_t *lun, uint16_t cdb_length, uint16_t task_ext)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_task_t *task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t cmd_slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_state & S_LINK_ONLINE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "cmd alloc called while the port"
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer " was offline");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rp_handle == FCT_HANDLE_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr(iport, rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "cmd received from "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "non existent port %x", rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rp_handle >= port->port_max_logins) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((irp = iport->iport_rp_slots[rp_handle]) == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "cmd received from "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "invalid port handle %x", rp_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_PRLI_DONE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "cmd alloc called while fcp "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "login was not done. portid=%x, rp=%p", rp->rp_id, rp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd = iport->iport_cached_cmdlist) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_cmdlist = icmd->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = (fct_cmd_t *)fct_alloc(FCT_STRUCT_CMD_FCP_XCHG,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer port->port_fca_fcp_cmd_size, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Ran out of "
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer "memory, port=%p", port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port = port;
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&iport->iport_total_alloced_ncmds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The accuracy of iport_max_active_ncmds is not important
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_total_alloced_ncmds - iport->iport_cached_ncmds) >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_max_active_ncmds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_max_active_ncmds =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_total_alloced_ncmds -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_ncmds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lets get a slot */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_slot = fct_alloc_cmd_slot(iport, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_slot == FCT_SLOT_EOL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Ran out of xchg resources");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_handle = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_fcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp = rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags |= ICMD_IN_TRANSITION | ICMD_KNOWN_TO_FCA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_specific = stmf_task_alloc(port->port_lport, irp->irp_session,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer lun, cdb_length, task_ext);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((task = (scsi_task_t *)cmd->cmd_specific) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_port_private = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_scsi_task_free(scsi_task_t *task)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = (fct_cmd_t *)task->task_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_comp_status = task->task_completion_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_post_rcvd_cmd(fct_cmd_t *cmd, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore fct_dbuf_store_t *fds;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_local_port_t *)cmd->cmd_port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_remote_port_t *)cmd->cmd_rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_task_t *task = (scsi_task_t *)cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t irp_task = irp->irp_fcp_xchg_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t load = iport->iport_total_alloced_ncmds -
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer iport->iport_cached_ncmds;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(scsi__command,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_local_port_t, iport,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer scsi_task_t, task,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (load >= iport->iport_task_green_limit) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((load < iport->iport_task_yellow_limit &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_task >= 4) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (load >= iport->iport_task_yellow_limit &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte load < iport->iport_task_red_limit &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_task >= 1) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (load >= iport->iport_task_red_limit))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_additional_flags |=
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer TASK_AF_PORT_LOAD_HIGH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore /*
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * If the target driver accepts sglists, fill in task fields.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore */
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore fds = cmd->cmd_port->port_fds;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore if (fds->fds_setup_dbuf != NULL) {
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_additional_flags |= TASK_AF_ACCEPT_LU_DBUF;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_copy_threshold = fds->fds_copy_threshold;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_max_xfer_len = fds->fds_max_sgl_xfer_len;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore /*
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * A single stream load encounters a little extra
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * latency if large xfers are done in 1 chunk.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * Give a hint to the LU that starting the xfer
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * with a smaller chunk would be better in this case.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * For any other load, use maximum chunk size.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore */
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore if (load == 1) {
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore /* estimate */
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_1st_xfer_len = 128*1024;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore } else {
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore /* zero means no hint */
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore task->task_1st_xfer_len = 0;
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore }
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore }
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_post_task((scsi_task_t *)cmd->cmd_specific, dbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_IN_TRANSITION);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We dont need dbuf for other cmds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dbuf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port->port_fds->fds_free_data_buf(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port->port_fds, dbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbuf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_els(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ABTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_rcvd_abts(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function bypasses fct_handle_els()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_post_implicit_logo(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_IMPLICIT_CMD_HAS_RESOURCE);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_nonfcp_xchg_count);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An implicit LOGO can also be posted to a irp where a PLOGI might
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be in process. That PLOGI will reset this flag and decrement the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iport_nrps_login counter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_PLOGI_DONE) {
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&iport->iport_nrps_login);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~(IRP_PLOGI_DONE | IRP_PRLI_DONE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_SESSION_AFFECTING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_discovery_queue(iport, irp, icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called with iport_lock held, return the slot number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint16_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_alloc_cmd_slot(fct_i_local_port_t *iport, fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t cmd_slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = iport->iport_next_free_slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_slot = old & 0xFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_slot == FCT_SLOT_EOL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd_slot);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We use high order 16 bits as a counter which keeps on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * incrementing to avoid ABA issues with atomic lists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = ((old + (0x10000)) & 0xFFFF0000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new |= iport->iport_cmd_slots[cmd_slot].slot_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&iport->iport_next_free_slot, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&iport->iport_nslots_free);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cmd_slots[cmd_slot].slot_cmd = icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_handle = (uint32_t)cmd_slot | 0x80000000 |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((uint32_t)(iport->iport_cmd_slots[cmd_slot].slot_uniq_cntr))
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer << 24);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd_slot);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If icmd is not NULL, irp_lock must be held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_post_to_discovery_queue(fct_i_local_port_t *iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp, fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t **p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = &irp->irp_els_list; *p != NULL;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer p = &((*p)->icmd_next))
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ;
ed2d37844dac0c702c0192fe78a02d8a08d2b81btim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *p = icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_IN_IRP_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_IN_DISCOVERY_QUEUE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CAUTION: do not grab local_port/remote_port locks after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * grabbing the worker lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_discovery_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rpwe_tail) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rpwe_tail->irp_discovery_next = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rpwe_tail = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rpwe_head = iport->iport_rpwe_tail = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_IN_DISCOVERY_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need always signal the port worker irrespective of the fact that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * irp is already in discovery queue or not.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_WORKER_SLEEPING(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_xfer_scsi_data(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = (fct_cmd_t *)task->task_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_5(xfer__start,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_local_port_t, cmd->cmd_port->port_fct_private,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer scsi_task_t, task,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, cmd->cmd_rp->rp_fct_private,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer stmf_data_buf_t, dbuf);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd->cmd_port->port_xfer_scsi_data(cmd, dbuf, ioflags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_scsi_data_xfer_done(fct_cmd_t *cmd, stmf_data_buf_t *dbuf, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t iof = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_5(xfer__done,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_local_port_t, cmd->cmd_port->port_fct_private,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer scsi_task_t, ((scsi_task_t *)cmd->cmd_specific),
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, cmd->cmd_rp->rp_fct_private,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer stmf_data_buf_t, dbuf);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioflags & FCT_IOF_FCA_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = new = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (old & ICMD_BEING_ABORTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new &= ~ICMD_KNOWN_TO_FCA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iof = STMF_IOF_LPORT_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_comp_status = dbuf->db_xfer_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_BEING_ABORTED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_data_xfer_done((scsi_task_t *)cmd->cmd_specific, dbuf, iof);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_send_scsi_status(scsi_task_t *task, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = (fct_cmd_t *)task->task_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(scsi__response,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_local_port_t,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_local_port_t *)cmd->cmd_port->port_fct_private,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer scsi_task_t, task,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (fct_i_remote_port_t *)cmd->cmd_rp->rp_fct_private);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd->cmd_port->port_send_cmd_response(cmd, ioflags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_send_response_done(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ioflags & FCT_IOF_FCA_DONE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Until we support confirmed completions, this is an error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = new = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (old & ICMD_BEING_ABORTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new &= ~ICMD_KNOWN_TO_FCA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_comp_status = s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_send_status_done((scsi_task_t *)cmd->cmd_specific, s,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer STMF_IOF_LPORT_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_sol_els_completion(iport, icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_CT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Tell the caller that we are done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_CMD_COMPLETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_free(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_abts_acc = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!mutex_owned(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Give the slot back */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (CMD_HANDLE_VALID(cmd->cmd_handle)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t n = CMD_HANDLE_SLOT_INDEX(cmd->cmd_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_slot_t *slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If anything went wrong, grab the lock as writer. This is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * probably unnecessary.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_comp_status != FCT_SUCCESS) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (icmd->icmd_flags & ICMD_ABTS_RECEIVED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd->icmd_flags & ICMD_ABTS_RECEIVED) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd->cmd_link != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_abts_acc = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX Validate slot before freeing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot = &iport->iport_cmd_slots[n];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_uniq_cntr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = iport->iport_next_free_slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot->slot_next = old & 0xFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = (old + 0x10000) & 0xFFFF0000;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new |= slot->slot_no;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&iport->iport_next_free_slot,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_handle = 0;
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&iport->iport_nslots_free);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_rp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = (fct_i_remote_port_t *)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer cmd->cmd_rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_fcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_nonfcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((icmd->icmd_flags & ICMD_IMPLICIT) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (icmd->icmd_flags & ICMD_IMPLICIT_CMD_HAS_RESOURCE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* for implicit cmd, no cmd slot is used */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_rp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = (fct_i_remote_port_t *)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer cmd->cmd_rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_fcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_nonfcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_abts_acc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *lcmd = cmd->cmd_link;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_fill_abts_acc(lcmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->port_send_cmd_response(lcmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_IOF_FORCE_FCA_DONE) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX Throw HBA fatal error event
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Later shutdown svc will terminate the ABTS in the end
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_cmd_free: iport-%p, ABTS_ACC"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " port_send_cmd_response failed", (void *)iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(lcmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_link = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Free the cmd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_cached_ncmds < max_cached_ncmds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_next = iport->iport_cached_cmdlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_cmdlist = icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_ncmds++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&iport->iport_total_alloced_ncmds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_scsi_abort(stmf_local_port_t *lport, int abort_cmd, void *arg,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen uint32_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_status_t ret = STMF_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_task_t *task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(abort_cmd == STMF_LPORT_ABORT_TASK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task = (scsi_task_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = (fct_cmd_t *)task->task_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fct_local_port_t *)lport->lport_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = new = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((old & ICMD_KNOWN_TO_FCA) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (STMF_NOT_FOUND);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((old & ICMD_FCA_ABORT_CALLED) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new |= ICMD_BEING_ABORTED | ICMD_FCA_ABORT_CALLED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->port_abort_cmd(port, cmd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret == FCT_NOT_FOUND) || (ret == FCT_ABORT_SUCCESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ret == FCT_BUSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_FCA_ABORT_CALLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_ctl(struct stmf_local_port *lport, int cmd, void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_change_status_t st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_change_status_t *pst;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((cmd == STMF_CMD_LPORT_ONLINE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd == STMF_ACK_LPORT_ONLINE_COMPLETE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd == STMF_CMD_LPORT_OFFLINE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd == STMF_ACK_LPORT_OFFLINE_COMPLETE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd == FCT_CMD_PORT_ONLINE_COMPLETE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd == FCT_CMD_PORT_OFFLINE_COMPLETE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fct_local_port_t *)lport->lport_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pst = (stmf_change_status_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_additional_info = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are mostly a passthrough, except during offline.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case STMF_CMD_LPORT_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_state == FCT_STATE_ONLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_ALREADY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (iport->iport_state != FCT_STATE_OFFLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_INVALID_ARG;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (st.st_completion_status != STMF_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &st);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_ONLINING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_ctl(port, FCT_CMD_PORT_ONLINE, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCT_CMD_PORT_ONLINE_COMPLETE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_state == FCT_STATE_ONLINING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pst->st_completion_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case STMF_ACK_LPORT_ONLINE_COMPLETE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_state == FCT_STATE_ONLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_ctl(port, FCT_ACK_PORT_ONLINE_COMPLETE, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case STMF_CMD_LPORT_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_state == FCT_STATE_OFFLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_ALREADY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (iport->iport_state != FCT_STATE_ONLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_INVALID_ARG;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (st.st_completion_status != STMF_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE, lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &st);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_OFFLINING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_ctl(port, FCT_CMD_PORT_OFFLINE, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCT_CMD_PORT_OFFLINE_COMPLETE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_state == FCT_STATE_OFFLINING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pst->st_completion_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE, lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pst);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If FCA's offline was successful, we dont tell stmf yet.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Becasue now we have to do the cleanup before we go upto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stmf. That cleanup is done by the worker thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FCA is offline, post a link down, its harmless anyway */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(port, FCT_EVENT_LINK_DOWN, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Trigger port offline processing by the worker */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_offline_prstate = FCT_OPR_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case STMF_ACK_LPORT_OFFLINE_COMPLETE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_state == FCT_STATE_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state_not_acked = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_ctl(port, FCT_ACK_PORT_OFFLINE_COMPLETE, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_info(uint32_t cmd, stmf_local_port_t *lport, void *arg, uint8_t *buf,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen uint32_t *bufsizep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (STMF_NOT_SUPPORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * implicit: if it's true, it means it will only be used in fct module, or else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it will be sent to the link.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_create_solels(fct_local_port_t *port, fct_remote_port_t *rp, int implicit,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t elsop, uint32_t wkdid, fct_icmd_cb_t icmdcb)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *p = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ptid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = (fct_cmd_t *)fct_alloc(FCT_STRUCT_CMD_SOL_ELS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fca_sol_els_private_size, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = RP_TO_IRP(rp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (((irp = fct_portid_to_portptr(PORT_TO_IPORT(port),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wkdid)) == NULL) && (elsop != ELS_OP_PLOGI)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(PORT_TO_IPORT(port)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_create_solels: Must PLOGI to %x first", wkdid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_oxid = PTR2INT(cmd, uint16_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rxid = 0xFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_handle = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = CMD_TO_ICMD(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els = ICMD_TO_ELS(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cb = icmdcb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp_handle = irp->irp_rp->rp_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rportid = irp->irp_rp->rp_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp_handle = FCT_HANDLE_NONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rportid = wkdid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_lportid = (PORT_TO_IPORT(port))->iport_link_info.portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (implicit) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since we will not send it to FCA, so we only allocate space
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(elsop & (ELS_OP_LOGO | ELS_OP_PLOGI));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags |= ICMD_IMPLICIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (elsop == ELS_OP_LOGO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handling implicit LOGO should dependent on as less
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as resources. So a trick here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_size = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload = cmd->cmd_fca_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_alloc_size = els->els_req_size = 116;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size = 116;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate space for its request and response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill the request payload according to spec.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (elsop) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case ELS_OP_LOGO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_alloc_size = els->els_req_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload = (uint8_t *)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ptid = PORT_TO_IPORT(port)->iport_link_info.portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_value_to_netbuf(ptid, els->els_req_payload + 5, 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_pwwn, els->els_req_payload + 8, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case ELS_OP_RSCN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_size = els->els_req_alloc_size = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload = (uint8_t *)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[1] = 0x04;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[3] = 0x08;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[4] |= 0x80;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ptid = PORT_TO_IPORT(port)->iport_link_info.portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_value_to_netbuf(ptid, els->els_req_payload + 5, 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case ELS_OP_PLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size = 116;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_alloc_size = els->els_req_size = 116;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_req_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_pwwn, p + 20, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_nwwn, p + 28, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common service parameters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x04] = 0x09; /* high version */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x05] = 0x08; /* low version */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x06] = 0x00; /* BB credit: 0x0065 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x07] = 0x65;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CI0: Continuously Increasing Offset - 1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* RRO: Randomly Relative Offset - 0 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* VVV: Vendor Version Level - 0 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* N-F: N or F Port Payload Sender - 0 (N) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* BBM: BB Credit Management - 0 (Normal) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x08] = 0x80;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x09] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Max RX size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0A] = 0x08;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0B] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NPTCS: N Port Total Concurrent Sequences - 0x0000 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0C] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0D] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ROIC: Relative Offset By Info - 0xFFFF */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0E] = 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x0F] = 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* EDTOV: Error Detect Timeout - 0x000007D0 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x10] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x11] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x12] = 0x07;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x13] = 0xD0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Class-3 Parameters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-VAL: Class 3 Value - 1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-XID: X_ID Reassignment - 0 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-IPA: Initial Process Assignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AI-DCC: Data compression capable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AI-DC-HB: Data compression history buffer size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AI-DCE: Data encrytion capable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AI-CSC: Clock synchronization capable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-ErrPol: Error pliciy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-CatSeq: Information Cat. Per Sequence */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AR-DCC: */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AR-DC-HB: */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AR-DCE: */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-AR-CSC */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x44] = 0x80;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x45] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x46] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x47] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x48] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x49] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-RxSize: Class 3 receive data size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x4A] = 0x08;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x4B] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-ConSeq: Class 3 Concourrent sequences */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x4C] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x4D] = 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* C3-OSPE: Class 3 open sequence per exchange */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x50] = 0x00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0x51] = 0x01;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case ELS_OP_SCR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_alloc_size = els->els_req_size = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_req_payload = (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(els->els_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[7] = FC_SCR_FULL_REGISTRATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
c946faca5d4627284fb79c6b04e652b471034495allan case ELS_OP_RLS:
c946faca5d4627284fb79c6b04e652b471034495allan els->els_resp_alloc_size = els->els_resp_size = 28;
c946faca5d4627284fb79c6b04e652b471034495allan els->els_resp_payload = (uint8_t *)
c946faca5d4627284fb79c6b04e652b471034495allan kmem_zalloc(els->els_resp_size, KM_SLEEP);
c946faca5d4627284fb79c6b04e652b471034495allan els->els_req_alloc_size = els->els_req_size = 8;
c946faca5d4627284fb79c6b04e652b471034495allan p = els->els_req_payload = (uint8_t *)
c946faca5d4627284fb79c6b04e652b471034495allan kmem_zalloc(els->els_req_size, KM_SLEEP);
c946faca5d4627284fb79c6b04e652b471034495allan ptid = PORT_TO_IPORT(port)->iport_link_info.portid;
c946faca5d4627284fb79c6b04e652b471034495allan fct_value_to_netbuf(ptid, els->els_req_payload + 5, 3);
c946faca5d4627284fb79c6b04e652b471034495allan break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[0] = elsop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_create_solct(fct_local_port_t *port, fct_remote_port_t *query_rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t ctop, fct_icmd_cb_t icmdcb)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *p = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *nname = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int namelen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate space
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fct_alloc(FCT_STRUCT_CMD_SOL_CT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fca_sol_ct_private_size, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We should have PLOGIed to the name server (0xFFFFFC)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caution: this irp is not query_rp->rp_fct_private.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr((fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private, FS_NAME_SERVER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(PORT_TO_IPORT(port)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_create_solct: Must PLOGI name server first");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp_handle = irp->irp_rp->rp_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rportid = irp->irp_rp->rp_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_lportid = (PORT_TO_IPORT(port))->iport_link_info.portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_oxid = PTR2INT(cmd, uint16_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rxid = 0xFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_handle = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = CMD_TO_ICMD(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct = ICMD_TO_CT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cb = icmdcb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ctop) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GSNN_NN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate max space for its sybolic name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 272;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(query_rp->rp_nwwn, p + 16, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RNN_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 28;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (iport->iport_link_info.portid >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (iport->iport_link_info.portid >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (iport->iport_link_info.portid >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Node Name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_nwwn, p + 20, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RCS_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (iport->iport_link_info.portid >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (iport->iport_link_info.portid >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (iport->iport_link_info.portid >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Class of Service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(p + 23) = FC_NS_CLASS3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RFT_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 52;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (iport->iport_link_info.portid >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (iport->iport_link_info.portid >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (iport->iport_link_info.portid >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC-4 Protocol Types
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(p + 22) = 0x1; /* 0x100 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSPN_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we get here, port->port_sym_port_name is always not NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->port_sym_port_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte namelen = strlen(port->port_sym_port_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size =
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (21 + namelen + 3) & ~3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (iport->iport_link_info.portid >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (iport->iport_link_info.portid >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (iport->iport_link_info.portid >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * String length
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[20] = namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Symbolic port name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_sym_port_name, p + 21, ct->ct_req_size - 21);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSNN_NN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte namelen = port->port_sym_node_name == NULL ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(utsname.nodename) :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(port->port_sym_node_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nname = port->port_sym_node_name == NULL ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte utsname.nodename : port->port_sym_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (25 + namelen + 3) & ~3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Node name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_nwwn, p + 16, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * String length
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[24] = namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Symbolic node name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(nname, p + 25, ct->ct_req_size - 25);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GSPN_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 272;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (query_rp->rp_id >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (query_rp->rp_id >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (query_rp->rp_id >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GCS_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (query_rp->rp_id >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (query_rp->rp_id >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (query_rp->rp_id >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GFT_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 48;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[17] = (query_rp->rp_id >> 16) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[18] = (query_rp->rp_id >> 8) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[19] = (query_rp->rp_id >> 0) & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GID_PN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_alloc_size = ct->ct_resp_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_resp_payload = (uint8_t *)kmem_zalloc(ct->ct_resp_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_size = ct->ct_req_alloc_size = 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = ct->ct_req_payload = (uint8_t *)kmem_zalloc(ct->ct_req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(query_rp->rp_pwwn, p + 16, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
bc85e3968c23ab6602e7c5ccc41cba0656c98391Dan McDonald FCT_FILL_CTIU_PREAMBLE(p, ctop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Cmd can only be solicited CT/ELS. They will be dispatched to the discovery
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * queue eventually too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We queue solicited cmds here to track solicited cmds and to take full use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of single thread mechanism.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But in current implmentation, we don't use this mechanism on SOL_CT, PLOGI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To avoid to interrupt current flow, ICMD_IN_SOLCMD_QUEUE is used here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_post_to_solcmd_queue(fct_local_port_t *port, fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_solcmd_next = iport->iport_solcmd_queue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_solcmd_queue = icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_IN_SOLCMD_QUEUE | ICMD_SOLCMD_NEW);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_WORKER_SLEEPING(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_event_handler(stmf_local_port_t *lport, int eventid, void *arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = (fct_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_scsi_session_t *ss;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (eventid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LPORT_EVENT_INITIAL_LUN_MAPPED:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ss = (stmf_scsi_session_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = (fct_i_remote_port_t *)ss->ss_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Initial LUN mapped to session ss-%p, irp-%p", ss, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unknown event received, %d", eventid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_send_cmd_done(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX For now just call send_resp_done() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_send_response_done(cmd, s, ioflags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_fca_aborted(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned long long st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st = s; /* To make gcc happy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(icmd->icmd_flags & ICMD_BEING_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((((s != FCT_ABORT_SUCCESS) && (s != FCT_NOT_FOUND))) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ioflags & FCT_IOF_FCA_DONE) == 0)) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan "fct_cmd_fca_aborted: cmd-%p, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "s-%llx, iofalgs-%x", (void *)cmd, st, ioflags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(cmd->cmd_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* For non FCP Rest of the work is done by the terminator */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* For FCP stuff just call stmf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_task_lport_aborted((scsi_task_t *)cmd->cmd_specific,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s, STMF_IOF_LPORT_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCA drivers will use it, when they want to abort some FC transactions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * due to lack of resource.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint16_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_get_rp_handle(fct_local_port_t *port, uint32_t rportid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fct_i_local_port_t *)(port->port_fct_private), rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0xFFFF);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (irp->irp_rp->rp_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_to_cmd(fct_local_port_t *port, uint32_t fct_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_slot_t *slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t ndx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!CMD_HANDLE_VALID(fct_handle))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ndx = CMD_HANDLE_SLOT_INDEX(fct_handle)) >= port->port_max_xchges)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte slot = &((fct_i_local_port_t *)port->port_fct_private)->iport_cmd_slots[
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ndx];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((slot->slot_uniq_cntr | 0x80) != (fct_handle >> 24))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (slot->slot_cmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_queue_scsi_task_for_termination(fct_cmd_t *cmd, fct_status_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((old & (ICMD_BEING_ABORTED | ICMD_KNOWN_TO_FCA)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_KNOWN_TO_FCA)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = old | ICMD_BEING_ABORTED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, (scsi_task_t *)cmd->cmd_specific,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer s, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_fill_abts_acc(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_rcvd_abts_t *abts = (fct_rcvd_abts_t *)cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte abts->abts_resp_rctl = BLS_OP_BA_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = abts->abts_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(p, 12);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *((uint16_t *)(p+4)) = BE_16(cmd->cmd_oxid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *((uint16_t *)(p+6)) = BE_16(cmd->cmd_rxid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[10] = p[11] = 0xff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_rcvd_abts(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *c = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *ic = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int found = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags |= ICMD_KNOWN_TO_FCA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make sure local port is sane */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_state & S_LINK_ONLINE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "ABTS not posted becasue"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port state was %x", iport->iport_link_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_LOCAL_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_rp_handle == FCT_HANDLE_NONE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr(iport, cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (cmd->cmd_rp_handle < port->port_max_logins)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_slots[cmd->cmd_rp_handle];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX Throw a logout to the initiator */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "ABTS received from"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x without a session", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_NOT_LOGGED_IN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan DTRACE_FC_3(abts__receive,
c946faca5d4627284fb79c6b04e652b471034495allan fct_cmd_t, cmd,
c946faca5d4627284fb79c6b04e652b471034495allan fct_local_port_t, port,
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_remote_port_t, irp);
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No need to allocate an xchg resource. ABTSes use the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * xchg resource as the cmd they are aborting.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lets find the command first */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < port->port_max_xchges; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ic = iport->iport_cmd_slots[i].slot_cmd) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ic->icmd_flags & ICMD_KNOWN_TO_FCA) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte c = ic->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!CMD_HANDLE_VALID(c->cmd_handle))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((c->cmd_rportid != cmd->cmd_rportid) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (c->cmd_oxid != cmd->cmd_oxid))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Found the command */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte found = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!found) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Dont even bother queueing it. Just respond */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_fill_abts_acc(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->port_send_cmd_response(cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_IOF_FORCE_FCA_DONE) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX Throw HBA fatal error event
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Later shutdown svc will terminate the ABTS in the end
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_handle_rcvd_abts: iport-%p, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ABTS_ACC port_send_cmd_response failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if this an abts retry */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (c->cmd_link && (ic->icmd_flags & ICMD_ABTS_RECEIVED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Kill this abts. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_q_for_termination_lock_held(iport, icmd, FCT_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_WORKER_SLEEPING(iport))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte c->cmd_link = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&ic->icmd_flags, ICMD_ABTS_RECEIVED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_link = c;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(c, FCT_ABTS_RECEIVED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_queue_cmd_for_termination(fct_cmd_t *cmd, fct_status_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_scsi_task_for_termination(cmd, s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_q_for_termination_lock_held(iport, icmd, s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_WORKER_SLEEPING(iport))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function will not be called for SCSI CMDS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_q_for_termination_lock_held(fct_i_local_port_t *iport, fct_i_cmd_t *icmd,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen fct_status_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t **ppicmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (old & ICMD_BEING_ABORTED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = old | ICMD_BEING_ABORTED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cmd->cmd_comp_status = s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppicmd = &(iport->iport_abort_queue); *ppicmd != NULL;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ppicmd = &((*ppicmd)->icmd_next))
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ;
ed2d37844dac0c702c0192fe78a02d8a08d2b81btim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ppicmd = icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For those cmds, for which we called fca_abort but it has not yet completed,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reset the FCA_ABORT_CALLED flag, so that abort can be called again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is done after a FCA offline. The reason is that after offline, the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * firmware is not running so abort will never complete. But if we call it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * again, the FCA will detect that it is not offline and it will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not call the firmware at all. Most likely it will abort in a synchronous
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * manner i.e. return FCT_ABORT_SUCCESS or FCT_NOT_FOUND.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_reset_flag_abort_called(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old, new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, do_clear;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < iport->iport_port->port_max_xchges; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_cmd_slots[i].slot_cmd == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = iport->iport_cmd_slots[i].slot_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old = new = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((old & (ICMD_KNOWN_TO_FCA |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_FCA_ABORT_CALLED)) == (ICMD_KNOWN_TO_FCA |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_FCA_ABORT_CALLED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new &= ~ICMD_FCA_ABORT_CALLED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_clear = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_clear = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&icmd->icmd_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_clear &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (icmd->icmd_cmd->cmd_type == FCT_CMD_FCP_XCHG)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_REQUEUE_TASK_ABORT_LPORT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cmd->cmd_specific, 0, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Modify the irp_deregister_timer such that the ports start deregistering
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * quickly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_irp_deregister_speedup(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iport->iport_nrps)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < rportid_table_size; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = iport->iport_rp_tb[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_deregister_timer = ddi_get_lbolt() - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_port_offline(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_offline_prstate == FCT_OPR_START) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_reset_flag_abort_called(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_offline_prstate = FCT_OPR_CMD_CLEANUP_WAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fct_ctl has already submitted a link offline event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_offline_prstate == FCT_OPR_CMD_CLEANUP_WAIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_state != PORT_STATE_LINK_DOWN)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All I/Os have been killed at this time. Lets speedup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the port deregister process.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_irp_deregister_speedup(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_offline_prstate = FCT_OPR_INT_CLEANUP_WAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_offline_prstate == FCT_OPR_INT_CLEANUP_WAIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_change_status_t st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_solcmd_queue) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_nrps) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A port logout may have gone when implicit logo all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was retried. So do the port speedup again here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_irp_deregister_speedup(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_event_head != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_completion_status = STMF_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_additional_info = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_offline_prstate = FCT_OPR_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state = FCT_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer iport->iport_port->port_lport, &st);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See stmf.h for information on rflags. Additional info is just a text
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * description of the reason for this call. Additional_info can be NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Also the caller can declare additional info on the stack. stmf_ctl
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * makes a copy of it before returning.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_port_initialize(fct_local_port_t *port, uint32_t rflags,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen char *additional_info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state_change_info_t st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_rflags = rflags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_additional_info = additional_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(NULL, "fct_port_initialize: port-%p, %s", port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte additional_info? additional_info : "no more information");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (stmf_ctl(STMF_CMD_LPORT_ONLINE, port->port_lport, &st));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_port_shutdown(fct_local_port_t *port, uint32_t rflags,
e4dcf6b386220918d8a355e951a2d7e8a73e5a6dTony Nguyen char *additional_info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state_change_info_t st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_rflags = rflags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st.st_additional_info = additional_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(NULL, "fct_port_shutdown: port-%p, %s", port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte additional_info? additional_info : "no more information");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (stmf_ctl(STMF_CMD_LPORT_OFFLINE, port->port_lport, &st));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called by worker thread. The aim is to terminate the command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * using whatever means it takes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with worker lock held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_cmd_terminator(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t endtime;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t **ppicmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = iport->iport_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t ret = DISC_ACTION_NO_WORK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t abort_ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fca_done, fct_done, cmd_implicit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned long long st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lets Limit each run to 20ms max. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte endtime = ddi_get_lbolt() + drv_usectohz(20000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start from where we left off last time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_ppicmd_term) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppicmd = iport->iport_ppicmd_term;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_ppicmd_term = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppicmd = &iport->iport_abort_queue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Once a command gets on discovery queue, this is the only thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which can access it. So no need for the lock here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((icmd = *ppicmd) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Always remember that cmd->cmd_rp can be NULL */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd->icmd_flags & (ICMD_KNOWN_TO_FCA |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_FCA_ABORT_CALLED)) == ICMD_KNOWN_TO_FCA) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_FCA_ABORT_CALLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (CMD_HANDLE_VALID(cmd->cmd_handle))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = FCT_IOF_FORCE_FCA_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte abort_ret = port->port_abort_cmd(port, cmd, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((abort_ret != FCT_SUCCESS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (abort_ret != FCT_ABORT_SUCCESS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (abort_ret != FCT_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flags & FCT_IOF_FORCE_FCA_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX trigger port fatal,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Abort the termination, and shutdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * svc will trigger fct_cmd_termination
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_cmd_terminator:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " iport-%p, port_abort_cmd with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "FORCE_FCA_DONE failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_ppicmd_term = ppicmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ~ICMD_FCA_ABORT_CALLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((flags & FCT_IOF_FORCE_FCA_DONE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (abort_ret == FCT_ABORT_SUCCESS) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (abort_ret == FCT_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= DISC_ACTION_DELAY_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (icmd->icmd_flags & ICMD_IMPLICIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_SOL_ELS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_comp_status = FCT_ABORTED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_FCA_ABORT_CALLED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_implicit = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd->icmd_flags & ICMD_KNOWN_TO_FCA) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_done = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_done = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd->icmd_flags & ICMD_IN_IRP_QUEUE) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_done = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_done = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fca_done || cmd_implicit) && fct_done) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(*ppicmd == icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ppicmd = (*ppicmd)->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_type == FCT_CMD_RCVD_ELS) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cmd->cmd_type == FCT_CMD_RCVD_ABTS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Free the cmd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_sol_els_completion(iport, icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_IMPLICIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IS_LOGO_ELS(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* IMPLICIT LOGO is special */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_CT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = ICMD_TO_CT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Tell the caller that we are done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_CMD_COMPLETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_netbuf_to_value(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_payload + 8, 2) == NS_GID_PN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_lookup_irp_by_portwwn(iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_payload + 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IRP_RSCN_QUEUED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t timeout_ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->port_fca_abort_timeout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_ticks = drv_usectohz(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fca_abort_timeout*1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 10 seconds by default */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_ticks = drv_usectohz(10 * 1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (icmd->icmd_start_time+timeout_ticks)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_state == FCT_STATE_ONLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* timeout, reset the port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char cmd_type[10];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(cmd_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (cmd_type), "%x.%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_CT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(cmd_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (cmd_type), "%x.%02x%02x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_payload[8],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct->ct_req_payload[9]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_type[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st = cmd->cmd_comp_status; /* gcc fix */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan "fct_cmd_terminator:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " iport-%p, cmd_type(0x%s),"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " reason(%llx)", (void *)iport, cmd_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte st);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppicmd = &((*ppicmd)->icmd_next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() > endtime) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_ppicmd_term = ppicmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_abort_queue)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == DISC_ACTION_NO_WORK)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send a syslog event for adapter port level events.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_log_local_port_event(fct_local_port_t *port, char *subclass)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_t *attr_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int port_instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fct_dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_instance = ddi_get_instance(fct_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_uint32(attr_list, "instance", port_instance)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_pwwn, 8) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_log_sysevent(fct_dip, DDI_VENDOR_SUNW, EC_SUNFC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subclass, attr_list, NULL, DDI_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteerror:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortealloc_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(((fct_i_local_port_t *)port->port_fct_private)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unable to send %s event", subclass);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_log_remote_port_event(fct_local_port_t *port, char *subclass,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *rp_pwwn, uint32_t rp_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_t *attr_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int port_instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fct_dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_instance = ddi_get_instance(fct_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_uint32(attr_list, "instance", port_instance)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_pwwn, 8) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "target-port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp_pwwn, 8) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_uint32(attr_list, "target-port-id",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp_id) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_log_sysevent(fct_dip, DDI_VENDOR_SUNW, EC_SUNFC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte subclass, attr_list, NULL, DDI_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteerror:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortealloc_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(((fct_i_local_port_t *)port->port_fct_private)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unable to send %s event", subclass);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint64_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_netbuf_to_value(uint8_t *buf, uint8_t nbytes)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t idx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= (buf[idx] << (8 * (nbytes -idx - 1)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (++idx < nbytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_value_to_netbuf(uint64_t value, uint8_t *buf, uint8_t nbytes)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t idx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (idx = 0; idx < nbytes; idx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf[idx] = 0xFF & (value >> (8 * (nbytes - idx - 1)));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer/*
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer * from_ptr: ptr to uchar_t array of size WWN_SIZE
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer * to_ptr: char ptr to string of size WWN_SIZE*2+1
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer */
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramervoid
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramerfct_wwn_to_str(char *to_ptr, const uint8_t *from_ptr)
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer{
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer ASSERT(to_ptr != NULL && from_ptr != NULL);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer (void) sprintf(to_ptr, "%02x%02x%02x%02x%02x%02x%02x%02x",
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer from_ptr[0], from_ptr[1], from_ptr[2], from_ptr[3],
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer from_ptr[4], from_ptr[5], from_ptr[6], from_ptr[7]);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer}
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allanstatic int
c946faca5d4627284fb79c6b04e652b471034495allanfct_update_stats(kstat_t *ks, int rw)
c946faca5d4627284fb79c6b04e652b471034495allan{
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_local_port_t *iport;
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_stat_t *port_kstat;
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_link_status_t stat;
c946faca5d4627284fb79c6b04e652b471034495allan uint32_t buf_size = sizeof (stat);
c946faca5d4627284fb79c6b04e652b471034495allan int ret;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (rw == KSTAT_WRITE)
c946faca5d4627284fb79c6b04e652b471034495allan return (EACCES);
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan iport = (fct_i_local_port_t *)ks->ks_private;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat = (fct_port_stat_t *)ks->ks_data;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_port->port_info == NULL) {
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan ret = iport->iport_port->port_info(FC_TGT_PORT_RLS,
c946faca5d4627284fb79c6b04e652b471034495allan iport->iport_port, NULL, (uint8_t *)&stat, &buf_size);
c946faca5d4627284fb79c6b04e652b471034495allan if (ret != STMF_SUCCESS) {
c946faca5d4627284fb79c6b04e652b471034495allan return (EIO);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->link_failure_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.LinkFailureCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->loss_of_sync_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.LossOfSyncCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->loss_of_signals_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.LossOfSignalsCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->prim_seq_protocol_err_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.PrimitiveSeqProtocolErrorCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->invalid_tx_word_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.InvalidTransmissionWordCount;
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat->invalid_crc_cnt.value.ui32 =
c946faca5d4627284fb79c6b04e652b471034495allan stat.InvalidCRCCount;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan return (0);
c946faca5d4627284fb79c6b04e652b471034495allan}
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allanvoid
c946faca5d4627284fb79c6b04e652b471034495allanfct_init_kstats(fct_i_local_port_t *iport)
c946faca5d4627284fb79c6b04e652b471034495allan{
c946faca5d4627284fb79c6b04e652b471034495allan kstat_t *ks;
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_stat_t *port_kstat;
c946faca5d4627284fb79c6b04e652b471034495allan char name[256];
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (iport->iport_alias)
c946faca5d4627284fb79c6b04e652b471034495allan (void) sprintf(name, "iport_%s", iport->iport_alias);
c946faca5d4627284fb79c6b04e652b471034495allan else
c946faca5d4627284fb79c6b04e652b471034495allan (void) sprintf(name, "iport_%"PRIxPTR"", (uintptr_t)iport);
c946faca5d4627284fb79c6b04e652b471034495allan ks = kstat_create(FCT_MODULE_NAME, 0, name, "rawdata",
c946faca5d4627284fb79c6b04e652b471034495allan KSTAT_TYPE_NAMED, sizeof (fct_port_stat_t) / sizeof (kstat_named_t),
c946faca5d4627284fb79c6b04e652b471034495allan 0);
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (ks == NULL) {
c946faca5d4627284fb79c6b04e652b471034495allan return;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan port_kstat = (fct_port_stat_t *)ks->ks_data;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan iport->iport_kstat_portstat = ks;
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->link_failure_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Link_failure_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->loss_of_sync_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Loss_of_sync_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->loss_of_signals_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Loss_of_signals_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->prim_seq_protocol_err_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Prim_seq_protocol_err_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->invalid_tx_word_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Invalid_tx_word_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan kstat_named_init(&port_kstat->invalid_crc_cnt,
c946faca5d4627284fb79c6b04e652b471034495allan "Invalid_crc_cnt", KSTAT_DATA_UINT32);
c946faca5d4627284fb79c6b04e652b471034495allan ks->ks_update = fct_update_stats;
c946faca5d4627284fb79c6b04e652b471034495allan ks->ks_private = (void *)iport;
c946faca5d4627284fb79c6b04e652b471034495allan kstat_install(ks);
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan}