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/*
8eec3430a514cd7c4e568f6dbe40d81b2f8f2d27Rijawanemohammadhusen Nadaf * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOT a DDI compliant Sun Fibre Channel port driver(fp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/varargs.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/param.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/uio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/buf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/modctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/poll.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/var.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/promif.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nvpair.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/byteorder.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/scsi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/fc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fc_ulpif.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fc_fcaif.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fctl_private.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fc_portif.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fibre-channel/impl/fp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* These are defined in fctl.c! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern int did_table_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern int pwwn_table_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct cb_ops fp_cb_ops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_open, /* open */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_close, /* close */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* strategy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* print */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* dump */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* read */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* write */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_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 | D_HOTPLUG, /* cb_flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_REV, /* rev */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev, /* aread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nodev /* awrite */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct dev_ops fp_ops = {
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao DEVO_REV, /* build revision */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao 0, /* reference count */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao fp_getinfo, /* getinfo */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao nulldev, /* identify - Obsoleted */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao nulldev, /* probe */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao fp_attach, /* attach */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao fp_detach, /* detach */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao nodev, /* reset */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao &fp_cb_ops, /* cb_ops */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao NULL, /* bus_ops */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao fp_power, /* power */
3cf42ffee6c3ea06731006f8faddee25ed957588Yu Renia Miao ddi_quiesce_not_needed /* quiesce */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
1770502e3d1e6d2a0c07529d1699cf722a70501bYu Renia Miao#define FP_VERSION "20091123-1.101"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FP_NAME_VERSION "SunFC Port v" FP_VERSION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *fp_version = FP_NAME_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modldrv modldrv = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mod_driverops, /* Type of Module */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_NAME_VERSION, /* Name/Version of fp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &fp_ops /* driver ops */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlinkage modlinkage = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODREV_1, /* Rev of the loadable modules system */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modldrv, /* NULL terminated list of */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL /* Linkage structures */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint16_t ns_reg_cmds[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RPN_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RNN_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RCS_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RFT_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RPT_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RSPN_ID,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_RSNN_NN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct fp_xlat {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t xlat_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int xlat_rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} fp_xlat [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_SUCCESS, FC_SUCCESS },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_REMOTE_STOP, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_LOCAL_RJT, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_NPORT_RJT, FC_ELS_PREJECT },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_FABRIC_RJT, FC_ELS_FREJECT },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_LOCAL_BSY, FC_TRAN_BUSY },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_TRAN_BSY, FC_TRAN_BUSY },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_NPORT_BSY, FC_PBUSY },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_FABRIC_BSY, FC_FBUSY },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_LS_RJT, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_BA_RJT, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_TIMEOUT, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_TRAN_ERROR, FC_TRANSPORT_ERROR },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_FAILURE, FC_FAILURE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_PORT_OFFLINE, FC_OFFLINE }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uchar_t fp_valid_alpas[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, 0x17, 0x18, 0x1B,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x1D, 0x1E, 0x1F, 0x23, 0x25, 0x26, 0x27, 0x29, 0x2A,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x32, 0x33, 0x34, 0x35,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x36, 0x39, 0x3A, 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, 0x81, 0x82,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, 0x9B, 0x9D, 0x9E,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, 0xA9, 0xAA, 0xAB, 0xAC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0xAD, 0xAE, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB9,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0xBA, 0xBC, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0xCC, 0xCD, 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0xD9, 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct fp_perms {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t fp_ioctl_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t fp_open_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} fp_perm_list [] = {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed { FCIO_GET_NUM_DEVS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_DEV_LIST, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_SYM_PNAME, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_SYM_NNAME, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_SET_SYM_PNAME, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_SET_SYM_NNAME, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_LOGI_PARAMS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DEV_LOGIN, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DEV_LOGOUT, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_STATE, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DEV_REMOVE, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_FCODE_REV, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_FW_REV, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_DUMP_SIZE, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_FORCE_DUMP, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_DUMP, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_TOPOLOGY, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_RESET_LINK, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_RESET_HARD, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_RESET_HARD_CORE, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DIAG, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_NS, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DOWNLOAD_FW, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DOWNLOAD_FCODE, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_LINK_STATUS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_HOST_PARAMS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_NODE_ID, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_SET_NODE_ID, FP_EXCL },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_SEND_NODE_ID, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_ADAPTER_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_OTHER_ADAPTER_PORTS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_ADAPTER_PORT_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_DISCOVERED_PORT_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_PORT_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_ADAPTER_PORT_STATS, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_ADAPTER_PORT_NPIV_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_NPIV_PORT_LIST, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_DELETE_NPIV_PORT, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_GET_NPIV_ATTRIBUTES, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_CREATE_NPIV_PORT, FP_OPEN },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FCIO_NPIV_GET_ADAPTER_ATTRIBUTES, FP_OPEN }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *fp_pm_comps[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "NAME=FC Port",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "0=Port Down",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "1=Port Up"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _LITTLE_ENDIAN
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed#define MAKE_BE_32(x) { \
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t *ptr1, i; \
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed ptr1 = (uint32_t *)(x); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sizeof (*(x)) / sizeof (uint32_t); i++) { \
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed *ptr1 = BE_32(*ptr1); \
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed ptr1++; \
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed } \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define MAKE_BE_32(x)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uchar_t fp_verbosity = (FP_WARNING_MESSAGES | FP_FATAL_MESSAGES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fp_options = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_cmd_wait_cnt = FP_CMDWAIT_DELAY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_retry_delay = FP_RETRY_DELAY; /* retry after this delay */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_retry_count = FP_RETRY_COUNT; /* number of retries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned int fp_offline_ticker; /* seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Driver global variable to anchor the list of soft state structs for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all fp driver instances. Used with the Solaris DDI soft state functions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *fp_driver_softstate;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic clock_t fp_retry_ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic clock_t fp_offline_ticks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_retry_ticker;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fp_unsol_buf_count = FP_UNSOL_BUF_COUNT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fp_unsol_buf_size = FP_UNSOL_BUF_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_log_size = FP_LOG_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int fp_trace = FP_TRACE_DEFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_trace_logq_t *fp_logq = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint fp_get_adapter_paths(char *pathList, int count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fp_log_port_event(fc_local_port_t *port, char *subclass);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fp_log_target_event(fc_local_port_t *port, char *subclass,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t tgt_pwwn, uint32_t port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t fp_map_remote_port_state(uint32_t rm_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fp_init_symbolic_names(fc_local_port_t *port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform global initialization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_init(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = ddi_soft_state_init(&fp_driver_softstate,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct fc_local_port), 8)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = scsi_hba_init(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_fini(&fp_driver_softstate);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logq = fc_trace_alloc_logq(fp_log_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = mod_install(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_free_logq(fp_logq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_fini(&fp_driver_softstate);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_hba_fini(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare for driver unload
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_fini(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = mod_remove(&modlinkage)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_free_logq(fp_logq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_fini(&fp_driver_softstate);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_hba_fini(&modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Request mod_info() to handle all cases
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_info(struct modinfo *modinfo)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mod_info(&modlinkage, modinfo));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_attach:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The respective cmd handlers take care of performing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULP related invocations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We check the value of fp_offline_ticker at this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * point. The variable is global for the driver and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not specific to an instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is no user-defined value found in /etc/system
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or fp.conf, then we use 90 seconds (FP_OFFLINE_TICKER).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The minimum setting for this offline timeout according
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the FC-FS2 standard (Fibre Channel Framing and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Signalling-2, see www.t11.org) is R_T_TOV == 100msec.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We do not recommend setting the value to less than 10
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * seconds (RA_TOV) or more than 90 seconds. If this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * variable is greater than 90 seconds then drivers above
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp (fcp, sd, scsi_vhci, vxdmp et al) might complain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_offline_ticker = ddi_prop_get_int(DDI_DEV_T_ANY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "fp_offline_ticker",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_OFFLINE_TICKER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fp_offline_ticker < 10) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fp_offline_ticker > 90)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "Setting fp_offline_ticker to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%d second(s). This is outside the "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "recommended range of 10..90 seconds",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_offline_ticker);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Tick every second when there are commands to retry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It should tick at the least granular value of pkt_timeout
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (which is one second)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_retry_ticker = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_retry_ticks = drv_usectohz(fp_retry_ticker * 1000 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_offline_ticks = drv_usectohz(fp_offline_ticker * 1000 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_attach_handler(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_resume_handler(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_detach:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a ULP fails to handle cmd request converse of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmd is invoked for ULPs that previously succeeded
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmd request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = DDI_FAILURE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_attach_cmd_t converse;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port = ddi_get_soft_state(fp_driver_softstate,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(dip))) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_ulp_attach) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_task != FP_TASK_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Let's attempt to quit the job handler gracefully */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_DETACH_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte converse = FC_CMD_ATTACH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_detach_ulps(port, FC_CMD_DETACH,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modlinkage) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 0; (port->fp_job_head) && (cnt < fp_cmd_wait_cnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_detach_handler(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte converse = FC_CMD_RESUME;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_detach_ulps(port, FC_CMD_SUSPEND,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modlinkage) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fp_suspend_handler(port)) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) callb_generic_cpr(&port->fp_cpr_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_CODE_CPR_RESUME);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use softint to perform reattach. Mark fp_ulp_attach so we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't attempt to do this repeatedly on behalf of some persistent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ulp_attach = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is in the low power mode then there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * possibility that fca too could be in low power mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to raise the power before calling attach ulps.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_soft_state & FP_SOFT_POWER_DOWN) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!(port->fp_soft_state & FP_SOFT_NO_PMCOMP))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) pm_raise_power(port->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_COMPONENT, FP_PM_PORT_UP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_attach_ulps(port, converse);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (port->fp_ulp_attach) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&port->fp_attach_cv, &port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark state as detach failed so asynchronous ULP attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * events (downstream, not the ones we're initiating with
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * the call to fp_attach_ulps) are not honored. We're
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * really still in pending detach.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_DETACH_FAILED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_getinfo:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given the device number, return either the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_info_t pointer or the instance number.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte minor_t instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = getminor((dev_t)arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2DEVINFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port = ddi_get_soft_state(fp_driver_softstate,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = (void *)port->fp_port_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_INFO_DEVT2INSTANCE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *result = (void *)(uintptr_t)instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Entry point for power up and power down request from kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_power(dev_info_t *dip, int comp, int level)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, ddi_get_instance(dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port == NULL || comp != FP_PM_COMPONENT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (level) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FP_PM_PORT_UP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is DDI_SUSPENDed, let the DDI_RESUME
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code complete the rediscovery.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_attach_ulps(port, FC_CMD_POWER_UP, &modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_POWER_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_pm_level == FP_PM_PORT_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_power_up(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FP_PM_PORT_DOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!(port->fp_soft_state & FP_SOFT_NO_PMCOMP));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_NO_PMCOMP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PM framework goofed up. We have don't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have any PM components. Let's never go down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_ulp_attach) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We shouldn't let the power go down */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not a whole lot to do if we are detaching
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_IN_DETACH) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!port->fp_pm_busy && !port->fp_pm_busy_nocomp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_power_down(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!(port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_POWER_DOWN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_POWER_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open FC port devctl node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_open(dev_t *devp, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otype != OTYP_CHR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is not a toy to play with. Allow only powerful
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * users (hopefully knowledgeable) to access the port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (A hacker potentially could download a sick binary
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file into FCA)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (drv_priv(credp)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EPERM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = (int)getminor(*devp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_flag & FP_EXCL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is already open for exclusive access.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So shut the door on this caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag & FEXCL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_flag & FP_OPEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Exclusive operation not possible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as it is already opened
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_flag |= FP_EXCL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_flag |= FP_OPEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The driver close entry point is called on the last close()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of a device. So it is perfectly alright to just clobber the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * open flag and reset it to idle (instead of having to reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * each flag bits). For any confusion, check out close(9E).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_close(dev_t dev, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otype != OTYP_CHR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = (int)getminor(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_flag & FP_OPEN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENODEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_flag = FP_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle IOCTL requests
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio_t fcio;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = (int)getminor(dev);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_flag & FP_OPEN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* this will raise power if necessary */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fctl_busy_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_pm_level == FP_PM_PORT_UP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_CMD: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _MULTI_DATAMODEL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ddi_model_convert_from(mode & FMODELS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_ILP32: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcio32 fcio32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)data, (void *)&fcio32,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct fcio32), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_xfer = fcio32.fcio_xfer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_cmd = fcio32.fcio_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_flags = fcio32.fcio_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_cmd_flags = fcio32.fcio_cmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_ilen = (size_t)fcio32.fcio_ilen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_ibuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr_t)(uintptr_t)fcio32.fcio_ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_olen = (size_t)fcio32.fcio_olen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_obuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr_t)(uintptr_t)fcio32.fcio_obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_alen = (size_t)fcio32.fcio_alen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_abuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr_t)(uintptr_t)fcio32.fcio_abuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio.fcio_errno = fcio32.fcio_errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_NONE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)data, (void *)&fcio,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcio_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* _MULTI_DATAMODEL */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)data, (void *)&fcio,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (fcio_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _MULTI_DATAMODEL */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_fciocmd(port, data, mode, &fcio);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fctl_ulp_port_ioctl(port, dev, cmd, data,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode, credp, rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Init Symbolic Port Name and Node Name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LV will try to get symbolic names from FCA driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and register these to name server,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if LV fails to get these,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LV will register its default symbolic names to name server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The Default symbolic node name format is :
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * <hostname>:<hba driver name>(instance)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The Default symbolic port name format is :
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * <fp path name>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_init_symbolic_names(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *vendorname = ddi_driver_name(port->fp_fca_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *sym_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char fcaname[50] = {0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int hostnlen, fcanlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_sym_node_namelen == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hostnlen = strlen(utsname.nodename);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(fcaname, sizeof (fcaname),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s%d", vendorname, ddi_get_instance(port->fp_fca_dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcanlen = strlen(fcaname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sym_name = kmem_zalloc(hostnlen + fcanlen + 2, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(sym_name, "%s:%s", utsname.nodename, fcaname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_namelen = strlen(sym_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_sym_node_namelen >= FCHBA_SYMB_NAME_LEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_namelen = FCHBA_SYMB_NAME_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(port->fp_sym_node_name, sym_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(sym_name, hostnlen + fcanlen + 2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_sym_port_namelen == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_pathname(port->fp_port_dip, pathname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_namelen = strlen(pathname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_sym_port_namelen >= FCHBA_SYMB_NAME_LEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_namelen = FCHBA_SYMB_NAME_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(port->fp_sym_port_name, pathname,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pathname, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform port attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_attach_handler(dev_info_t *dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int port_num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int port_len;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char name[30];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char i_pwwn[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ub_count;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *phyport = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portpro1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char pwwn[17], nwwn[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_len = sizeof (port_num);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "port",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&port_num, &port_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): No port property in devinfo",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): failed to create devctl minor node",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "fc", S_IFCHR, instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_NT_FC_ATTACHMENT_POINT, 0) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): failed to create fc attachment"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " point minor node", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_soft_state_zalloc(fp_driver_softstate, instance)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): failed to alloc soft state",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(port->fp_ibuf, "fp(%d)", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance = instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ulp_attach = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_num = port_num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_verbose = fp_verbosity;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options = fp_options;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_dip = ddi_get_parent(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_dip = dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran = (fc_fca_tran_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_driver_private(port->fp_fca_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Init the starting value of fp_rscn_count. Note that if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_INVALID_RSCN_COUNT is 0 (which is what it currently is), the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * actual # of RSCNs will be (fp_rscn_count - 1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_rscn_count = FC_INVALID_RSCN_COUNT + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&port->fp_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&port->fp_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&port->fp_attach_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(name, "fp%d_cache", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((portpro1 = ddi_prop_get_int(DDI_DEV_T_ANY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dip, DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "phyport-instance", -1)) != -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyport = ddi_get_soft_state(fp_driver_softstate, portpro1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&phyport->fp_service_params.nport_ww_name, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&phyport->fp_service_params.node_ww_name, nwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_npiv_type = FC_NPIV_PORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate the pool of fc_packet_t structs to be used with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this fp instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pkt_cache = kmem_cache_create(name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_fca_tran->fca_pkt_size) + sizeof (fp_cmd_t), 8,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cache_constructor, fp_cache_destructor, NULL, (void *)port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, 0);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pkt_cache == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto cache_alloc_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate the d_id and pwwn hash tables for all remote ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * connected to this local port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_did_table = kmem_zalloc(did_table_size *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct d_id_hash), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pwwn_table = kmem_zalloc(pwwn_table_size *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct pwwn_hash), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_taskq = taskq_create("fp_ulp_callback", 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MINCLSYSPRI, 1, 16, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Indicate that don't have the pm components yet */
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_soft_state |= FP_SOFT_NO_PMCOMP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bind the callbacks with the FCA driver. This will open the gate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for asynchronous callbacks, so after this call the fp_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * must be held when updating the fc_local_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is done _before_ setting up the job thread so we can avoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cleaning up after the thread_create() in the error path. This
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * also means fp will be operating with fp_els_resp_pkt set to NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_bind_callbacks(port) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto bind_callbacks_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (phyport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&phyport->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (phyport->fp_port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyport->fp_port_next->fp_port_prev = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_next = phyport->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyport->fp_port_next = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_prev = phyport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyport->fp_port_next = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyport->fp_port_prev = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_next = phyport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_prev = phyport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&phyport->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Init Symbolic Names
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_init_symbolic_names(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = fp_alloc_pkt(port, sizeof (la_els_logi_t), sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): failed to allocate ELS packet",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_els_packet_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) thread_create(NULL, 0, fp_job_handler, port, 0, &p0, TS_RUN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte v.v_maxsyspri - 2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&port->fp_service_params.nport_ww_name, i_pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "initiator-port",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_pwwn) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp(%d): Updating 'initiator-port' property"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " on fp dev_info node failed", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&port->fp_service_params.node_ww_name, i_pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "initiator-node",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_pwwn) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp(%d): Updating 'initiator-node' property"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " on fp dev_info node failed", instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt = pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine the count of unsolicited buffers this FCA can support
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_retrieve_caps(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate unsolicited buffer tokens
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_ub_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_count = port->fp_ub_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens = kmem_zalloc(ub_count *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*port->fp_ub_tokens), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do not fail the attach if unsolicited buffer allocation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fails; Just try to get along with whatever the FCA can do.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_uballoc(port, &ub_count, fp_unsol_buf_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_TYPE_EXTENDED_LS, port->fp_ub_tokens) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS || ub_count != port->fp_ub_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): failed to allocate "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Unsolicited buffers. proceeding with attach...",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_ub_tokens,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*port->fp_ub_tokens) * port->fp_ub_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_load_ulp_modules(dip, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Enable DDI_SUSPEND and DDI_RESUME for this instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pm-hardware-state", "needs-suspend-resume",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen("needs-suspend-resume") + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl maintains a list of all port handles, so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * help fctl add this one to its list now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_add_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a state change is already in progress, set the bind state t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OFFLINE as well, so further state change callbacks into ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will pass the appropriate states
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_bind_state) == FC_STATE_OFFLINE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_bind_state = FC_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_startup_done((opaque_t)port, FC_PKT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Without dropping the mutex, ensure that the port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * startup happens ahead of state change callback
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * processing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_job_tail == NULL && port->fp_job_head == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = port->fp_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = FP_TASK_PORT_STARTUP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_STARTUP, JOB_TYPE_FCTL_ASYNC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_startup_done, (opaque_t)port, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_head = port->fp_job_tail = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (port->fp_ulp_attach) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&port->fp_attach_cv, &port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pm-components", fp_pm_comps,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fp_pm_comps) / sizeof (fp_pm_comps[0])) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0), "Failed to create PM"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " components property, PM disabled on this port.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_raise_power(dip, FP_PM_COMPONENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_PORT_UP) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0), "Failed to raise"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " power level");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_level = FP_PM_PORT_UP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't unset the FP_SOFT_NO_PMCOMP flag until after
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * the call to pm_raise_power. The PM framework can't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle multiple threads calling into it during attach.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_soft_state &= ~FP_SOFT_NO_PMCOMP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_report_dev(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_port_event(port, ESC_SUNFC_PORT_ATTACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unwind any/all preceeding allocations in the event of an error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortealloc_els_packet_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_fca_handle != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_unbind_port(port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_ub_tokens != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_ubfree(port, port->fp_ub_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_ub_tokens,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_count * sizeof (*port->fp_ub_tokens));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_els_resp_pkt != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(port->fp_els_resp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortebind_callbacks_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_taskq != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_destroy(port->fp_taskq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pwwn_table != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_pwwn_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_table_size * sizeof (struct pwwn_hash));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pwwn_table = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_did_table != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_did_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_table_size * sizeof (struct d_id_hash));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_did_table = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pkt_cache != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(port->fp_pkt_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pkt_cache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecache_alloc_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&port->fp_attach_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(port->fp_port_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_free(fp_driver_softstate, instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_remove_all(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle DDI_RESUME request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_resume_handler(dev_info_t *dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = ddi_get_soft_state(fp_driver_softstate, ddi_get_instance(dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_soft_state & FP_SOFT_SUSPEND);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port was power suspended, raise the power level
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_soft_state & FP_SOFT_POWER_DOWN) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!(port->fp_soft_state & FP_SOFT_NO_PMCOMP))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_pm_level == FP_PM_PORT_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_raise_power(dip, FP_PM_COMPONENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_PORT_UP) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Failed to raise the power level");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All the discovery is initiated and handled by per-port thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Further all the discovery is done in handled in callback mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (not polled mode); In a specific case such as this, the discovery
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is required to happen in polled mode. The easiest way out is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to bail out port thread and get started. Come back and fix this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do on demand discovery initiated by ULPs. ULPs such as FCP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will do on-demand discovery during pre-power-up busctl handling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which will only be possible when SCSA provides a new HBA vector
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for sending down the PM busctl requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) callb_generic_cpr(&port->fp_cpr_info, CB_CODE_CPR_RESUME);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_resume_all(port, FC_CMD_RESUME);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) callb_generic_cpr(&port->fp_cpr_info,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CB_CODE_CPR_CHKPT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform FC Port power on initialization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_power_up(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((port->fp_soft_state & FP_SOFT_SUSPEND) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_soft_state & FP_SOFT_POWER_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_resume_all(port, FC_CMD_POWER_UP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is important to note that the power may possibly be removed between
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SUSPEND and the ensuing RESUME operation. In such a context the underlying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC port hardware would have gone through an OFFLINE to ONLINE transition
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (hardware state). In this case, the port driver may need to rediscover the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * topology, perform LOGINs, register with the name server again and perform
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any such port initialization procedures. To perform LOGINs, the driver could
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * use the port device handle to see if a LOGIN needs to be performed and use
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the D_ID and WWN in it. The LOGINs may fail (if the hardware is reconfigured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or removed) which will be reflected in the map the ULPs will see.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_resume_all(fc_local_port_t *port, fc_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_bind_callbacks(port) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are commands queued for delayed retry, instead of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * working the hard way to figure out which ones are good for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * restart and which ones not (ELSs are definitely not good
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as the port will have to go through a new spin of rediscovery
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * now), so just flush them out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_restore & FP_RESTORE_WAIT_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_restore &= ~FP_RESTORE_WAIT_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((cmd = fp_deque_cmd(port)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state = FC_PKT_TRAN_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_bind_state) == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_restore & FP_RESTORE_OFFLINE_TIMEOUT) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_restore &= ~FP_RESTORE_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = timeout(fp_offline_timeout,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)port, fp_offline_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_attach_ulps(port, cmd, &modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct job_request *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an OFFLINE timer was running at the time of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * suspending, there is no need to restart it as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the port is ONLINE now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_restore &= ~FP_RESTORE_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_ONLINE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_CANCEL_ULP_NOTIFICATION, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_remove_oldies(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_attach_ulps(port, cmd, &modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this time, there shouldn't be any I/O requests on this port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But the unsolicited callbacks from the underlying FCA port need
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to be handled very carefully. The steps followed to handle the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DDI_DETACH are:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * + Grab the port driver mutex, check if the unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callback is currently under processing. If true, fail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the DDI_DETACH request by printing a message; If false
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mark the DDI_DETACH as under progress, so that any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * further unsolicited callbacks get bounced.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Perform PRLO/LOGO if necessary, cleanup all the data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Get the job_handler thread to gracefully exit.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Unregister callbacks with the FCA port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Now that some peace is found, notify all the ULPs of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DDI_DETACH request (using ulp_port_detach entry point)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Free all mutexes, semaphores, conditional variables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * + Free the soft state, return success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Important considerations:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port driver de-registers state change and unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * callbacks before taking up the task of notifying ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and performing PRLO and LOGOs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A port may go offline at the time PRLO/LOGO is being
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requested. It is expected of all FCA drivers to fail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * such requests either immediately with a FC_OFFLINE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return code to fc_fca_transport() or return the packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * asynchronously with pkt state set to FC_PKT_PORT_OFFLINE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_detach_handler(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t delay_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *orp, *tmporp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In a Fabric topology with many host ports connected to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a switch, another detaching instance of fp might have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * triggered a LOGO (which is an unsolicited request to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this instance). So in order to be able to successfully
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * detach by taking care of such cases a delay of about
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 30 seconds is introduced.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (port->fp_out_fpcmds != 0) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed /*
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * At this time we can only check fp internal commands, because
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * sd/ssd/scsi_vhci should have finsihed all their commands,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * fcp/fcip/fcsm should have finished all their commands.
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * It seems that all fp internal commands are asynchronous now.
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed */
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed cmn_err(CE_WARN, "fp(%d): %d fp_cmd(s) is/are in progress"
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed " Failing detach", port->fp_instance, port->fp_out_fpcmds);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed return (DDI_FAILURE);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (delay_count < 30)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Failing detach", port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_DETACH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we're powered down, we need to raise power prior to submitting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the JOB_PORT_SHUTDOWN job. Otherwise, the job handler will never
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * process the shutdown job.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_busy_port(port) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): fctl_busy_port failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_DETACH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will deallocate data structs and cause the "job" thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to exit, in preparation for DDI_DETACH on the instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This can sleep for an arbitrary duration, since it waits for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * commands over the wire, timeout(9F) callbacks, etc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CAUTION: There is still a race here, where the "job" thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can still be executing code even tho the fctl_jobwait() call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * below has returned to us. In theory the fp driver could even be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modunloaded even tho the job thread isn't done executing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * without creating the race condition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_SHUTDOWN, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)port, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) pm_lower_power(port->fp_port_dip, FP_PM_COMPONENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_PORT_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_taskq) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_destroy(port->fp_taskq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_remove_all(port->fp_port_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_remove_minor_node(port->fp_port_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_remove_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(port->fp_els_resp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_ub_tokens) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_ubfree(port, port->fp_ub_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): couldn't free "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " unsolicited buffers", port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_ub_tokens,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*port->fp_ub_tokens) * port->fp_ub_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_tokens = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pkt_cache != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(port->fp_pkt_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_unbind_port(port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_did_table) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_did_table, did_table_size *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (struct d_id_hash));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pwwn_table) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port->fp_pwwn_table, pwwn_table_size *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct pwwn_hash));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp = port->fp_orphan_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (orp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmporp = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(tmporp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_port_event(port, ESC_SUNFC_PORT_DETACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&port->fp_attach_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_soft_state_free(fp_driver_softstate, port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Steps to perform DDI_SUSPEND operation on a FC port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If already suspended return DDI_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If already power-suspended return DDI_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If an unsolicited callback or state change handling is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in progress, throw a warning message, return DDI_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Cancel timeouts
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - SUSPEND the job_handler thread (means do nothing as it is
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * taken care of by the CPR frame work)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_suspend_handler(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t delay_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The following should never happen, but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * let the driver be more defensive here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is already power suspended, there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is nothing else to do, So return DDI_SUCCESS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but mark the SUSPEND bit in the soft state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * before leaving.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_POWER_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if an unsolicited callback or state change handling is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in progress. If true, fail the suspend operation; also throw
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a warning message notifying the failure. Note that Sun PCI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hotplug spec recommends messages in cases of failure (but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not flooding the console)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Busy waiting for a short interval (500 millisecond ?) to see
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the callback processing completes may be another idea. Since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * most of the callback processing involves a lot of work, it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is safe to just fail the SUSPEND operation. It is definitely
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not bad to fail the SUSPEND operation if the driver is busy.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_IN_UNSOL_CB)) && (delay_count < 30)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_IN_UNSOL_CB)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Failing suspend", port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check of FC port thread is busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "FC port thread is busy: Failing suspend");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_suspend_all(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare for graceful power down of a FC port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_power_down(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Power down request followed by a DDI_SUSPEND should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * never happen; If it does return DDI_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is already power suspended, there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is nothing else to do, So return DDI_SUCCESS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_POWER_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if an unsolicited callback or state change handling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is in progress. If true, fail the PM suspend operation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But don't print a message unless the verbosity of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver desires otherwise.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_soft_state & FP_SOFT_IN_STATEC_CB) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_soft_state & FP_SOFT_IN_UNSOL_CB)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsolicited callback in progress: Failing power down");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check of FC port thread is busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "FC port thread is busy: Failing power down");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if the ULPs are ready for power down
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_detach_ulps(port, FC_CMD_POWER_DOWN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &modlinkage) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Power back up the obedient ULPs that went down
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_attach_ulps(port, FC_CMD_POWER_UP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ULP(s) busy, detach_ulps failed. Failing power down");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_suspend_all(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Suspend the entire FC port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_suspend_all(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed struct pwwn_hash *head;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_tid != 0) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = port->fp_wait_tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = (timeout_id_t)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_restore |= FP_RESTORE_WAIT_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_offline_tid) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = port->fp_offline_tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = (timeout_id_t)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_restore |= FP_RESTORE_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_unbind_port(port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark all devices as OLD, and reset the LOGIN state as well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (this will force the ULPs to perform a LOGIN after calling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_portgetmap() during RESUME/PM_RESUME)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_remote_port_offline(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_cache_constructor: Constructor function for kmem_cache_create(9F).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs intializations for fc_packet_t structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 for success or -1 for failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function allocates DMA handles for both command and responses.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Most of the ELSs used have both command and responses so it is strongly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * desired to move them to cache constructor routine.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context: Can sleep iff called with KM_SLEEP flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_cache_constructor(void *buf, void *cdarg, int kmflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int (*cb) (caddr_t);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd = (fp_cmd_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = (fc_local_port_t *)cdarg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb = (kmflags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(port->fp_soft_state & FP_SOFT_FCA_IS_NODMA)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ddi_dma_alloc_handle(port->fp_fca_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_attr, cb, NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &pkt->pkt_cmd_dma) != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (-1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ddi_dma_alloc_handle(port->fp_fca_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_attr, cb, NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &pkt->pkt_resp_dma) != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_dma_free_handle(&pkt->pkt_cmd_dma);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (-1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_cmd_dma = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_resp_dma = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_acc = pkt->pkt_resp_acc = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie_cnt = pkt->pkt_resp_cookie_cnt =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_data_cookie_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie = pkt->pkt_resp_cookie =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_data_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_fca_private = (caddr_t)buf + sizeof (fp_cmd_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_cache_destructor: Destructor function for kmem_cache_create().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs un-intializations for fc_packet_t structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_cache_destructor(void *buf, void *cdarg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd = (fp_cmd_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_cmd_dma) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_free_handle(&pkt->pkt_cmd_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_dma) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_free_handle(&pkt->pkt_resp_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Packet allocation for ELS and any other port driver commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some ELSs like FLOGI and PLOGI are critical for topology and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device discovery and a system's inability to allocate memory
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or DVMA resources while performing some of these critical ELSs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cause a lot of problem. While memory allocation failures are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rare, DVMA resource failures are common as the applications
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * are becoming more and more powerful on huge servers. So it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is desirable to have a framework support to reserve a fragment
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of DVMA. So until this is fixed the correct way, the suffering
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is huge whenever a LIP happens at a time DVMA resources are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * drained out completely - So an attempt needs to be made to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * KM_SLEEP while requesting for these resources, hoping that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the requests won't hang forever.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fc_remote_port_t argument is stored into the pkt_pd field in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_packet_t struct prior to the fc_ulp_init_packet() call. This
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ensures that the pd_ref_count for the fc_remote_port_t is valid.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there is no fc_remote_port_t associated with the fc_packet_t, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_alloc_pkt() must be called with pd set to NULL.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fp/fctl will resue fp_cmd_t somewhere, and change pkt_cmdlen/rsplen,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * actually, it's a design fault. But there's no problem for physical
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCAs. But it will cause memory leak or panic for virtual FCAs like fcoei.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * For FCAs that don't support DMA, such as fcoei, we will use
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * pkt_fctl_rsvd1/rsvd2 to keep the real cmd_len/resp_len.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fp_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_alloc_pkt(fc_local_port_t *port, int cmd_len, int resp_len, int kmflags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulong_t real_len;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int (*cb) (caddr_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_cookie_t *cp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb = (kmflags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = (fp_cmd_t *)kmem_cache_alloc(port->fp_pkt_cache, kmflags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_dflags == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_datalen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_data = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_action = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_expln = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_cmd = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_resp = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_fctl_rsvd1 = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_fctl_rsvd2 = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Init pkt_pd with the given pointer; this must be done _before_
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the call to fc_ulp_init_packet().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now call the FCA driver to init its private, per-packet fields */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_ulp_init_packet((opaque_t)port, pkt, kmflags) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (cmd_len && !(port->fp_soft_state & FP_SOFT_FCA_IS_NODMA)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt->pkt_cmd_dma != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_dma_mem_alloc(pkt->pkt_cmd_dma, cmd_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_acc_attr, DDI_DMA_CONSISTENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb, NULL, (caddr_t *)&pkt->pkt_cmd, &real_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt->pkt_cmd_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags |= FP_CMD_VALID_DMA_MEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (real_len < cmd_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_dma_addr_bind_handle(pkt->pkt_cmd_dma, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd, real_len, DDI_DMA_WRITE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_CONSISTENT, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt_cookie, &pkt->pkt_cmd_cookie_cnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_DMA_MAPPED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags |= FP_CMD_VALID_DMA_BIND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_cmd_cookie_cnt >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_dma_attr->dma_attr_sgllen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt->pkt_cmd_cookie_cnt != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp = pkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt < pkt->pkt_cmd_cookie_cnt; cnt++, cp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_nextcookie(pkt->pkt_cmd_dma, &pkt_cookie);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (cmd_len != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_cmd = kmem_alloc(cmd_len, KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_fctl_rsvd1 = (opaque_t)(uintptr_t)cmd_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (resp_len && !(port->fp_soft_state & FP_SOFT_FCA_IS_NODMA)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt->pkt_resp_dma != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_dma_mem_alloc(pkt->pkt_resp_dma, resp_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_acc_attr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_CONSISTENT, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t *)&pkt->pkt_resp, &real_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt->pkt_resp_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags |= FP_RESP_VALID_DMA_MEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (real_len < resp_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_dma_addr_bind_handle(pkt->pkt_resp_dma, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp, real_len, DDI_DMA_READ |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DMA_CONSISTENT, cb, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pkt_cookie, &pkt->pkt_resp_cookie_cnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_DMA_MAPPED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags |= FP_RESP_VALID_DMA_BIND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_cookie_cnt >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_dma_attr->dma_attr_sgllen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt->pkt_cmd_cookie_cnt != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp = pkt->pkt_resp_cookie = (ddi_dma_cookie_t *)kmem_alloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp_cookie_cnt * sizeof (pkt_cookie),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto alloc_pkt_failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt < pkt->pkt_resp_cookie_cnt; cnt++, cp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_nextcookie(pkt->pkt_resp_dma, &pkt_cookie);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *cp = pkt_cookie;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (resp_len != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_resp = kmem_alloc(resp_len, KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_fctl_rsvd2 = (opaque_t)(uintptr_t)resp_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmdlen = cmd_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_rsplen = resp_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_ulp_private = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortealloc_pkt_failed:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_dma(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_cmd_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pkt->pkt_cmd_cookie,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie_cnt * sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pkt->pkt_resp_cookie,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp_cookie_cnt * sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (port->fp_soft_state & FP_SOFT_FCA_IS_NODMA) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pkt->pkt_cmd) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(pkt->pkt_cmd, cmd_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pkt->pkt_resp) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(pkt->pkt_resp, resp_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_free(port->fp_pkt_cache, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free FC packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_free_pkt(fp_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&cmd->cmd_port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_ulp_private = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_cmd_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pkt->pkt_cmd_cookie, pkt->pkt_cmd_cookie_cnt *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_cookie != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pkt->pkt_resp_cookie, pkt->pkt_resp_cookie_cnt *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ddi_dma_cookie_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp_cookie = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (port->fp_soft_state & FP_SOFT_FCA_IS_NODMA) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pkt->pkt_cmd) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(pkt->pkt_cmd,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint32_t)(uintptr_t)pkt->pkt_fctl_rsvd1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pkt->pkt_resp) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(pkt->pkt_resp,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint32_t)(uintptr_t)pkt->pkt_fctl_rsvd2);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_dma(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_uninit_packet((opaque_t)port, pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_free(port->fp_pkt_cache, (void *)cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release DVMA resources
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_free_dma(fp_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmdlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_dflags & FP_CMD_VALID_DMA_BIND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_dma_unbind_handle(pkt->pkt_cmd_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_dflags & FP_CMD_VALID_DMA_MEM) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_cmd_acc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_mem_free(&pkt->pkt_cmd_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_dflags & FP_RESP_VALID_DMA_BIND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_dma_unbind_handle(pkt->pkt_resp_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_dflags & FP_RESP_VALID_DMA_MEM) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_acc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_mem_free(&pkt->pkt_resp_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_dflags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dedicated thread to perform various activities. One thread for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * each fc_local_port_t (driver soft state) instance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note, this effectively works out to one thread for each local
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port, but there are also some Solaris taskq threads in use on a per-local
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port basis; these also need to be taken into consideration.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_job_handler(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Solaris-internal stuff for proper operation of kernel threads
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with Solaris CPR.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_INIT(&port->fp_cpr_info, &port->fp_mutex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte callb_generic_cpr, "fp_job_handler");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop forever waiting for work to do */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (;;) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sleep if no work to do right now, or if we want
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to suspend or power-down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (port->fp_job_head == NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_soft_state & (FP_SOFT_POWER_DOWN |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_SUSPEND))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_SAFE_BEGIN(&port->fp_cpr_info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&port->fp_cv, &port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_SAFE_END(&port->fp_cpr_info, &port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OK, we've just been woken up, so retrieve the next entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from the head of the job queue for this local port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_deque_job(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle all the fp driver's supported job codes here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in this big honkin' switch.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (job->job_code) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_SHUTDOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_port_shutdown() is only called from here. This
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will prepare the local port instance (softstate)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for detaching. This cancels timeout callbacks,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * executes LOGOs with remote ports, cleans up tables,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and deallocates data structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_port_shutdown(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will exit the job thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CALLB_CPR_EXIT(&(port->fp_cpr_info));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thread_exit();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_ATTACH_ULP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This job is spawned in response to a ULP calling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_add().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte boolean_t do_attach_ulps = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fp is detaching, we don't want to call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_startup_done as this asynchronous
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * notification may interfere with the re-attach.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & (FP_DETACH_INPROGRESS |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_IN_DETACH | FP_DETACH_FAILED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_attach_ulps = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are going to force the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to attach to the ULPs, so set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_ulp_attach. This will keep any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * potential detach from occurring until
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ulp_attach = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: Since we just dropped the mutex, there is now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a race window where the fp_soft_state check above
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * could change here. This race is covered because an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * additional check was added in the functions hidden
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * under fp_startup_done().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_attach_ulps == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This goes thru a bit of a convoluted call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * chain before spawning off a DDI taskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request to perform the actual attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operations. Blocking can occur at a number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of points.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_startup_done((opaque_t)port, FC_PKT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_ULP_NOTIFY: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pass state change notifications up to any/all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * registered ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t statec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte statec = job->job_ulp_listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (statec == FC_STATE_RESET_REQUESTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = port->fp_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = FP_TASK_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_port_offline(port, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = fp_ulp_notify(port, statec, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PLOGI_ONE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Issue a PLOGI to a single remote port. Multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGIs to different remote ports may occur in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parallel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This can create the fc_remote_port_t if it does not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * already exist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = (uint32_t *)job->job_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, *d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fp_create_remote_port_by_ns(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *d_id, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, *d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, KM_SLEEP, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_LOGO_ONE: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Issue a PLOGO to a single remote port. Multiple
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGOs to different remote ports may occur in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parallel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_counter > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = (fc_remote_port_t *)job->job_ulp_pkts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_LOGINREQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_login_count > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_logout(port, pd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_FCIO_LOGIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI initiated at ioctl request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fcio_login(port, job->job_private, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_FCIO_LOGOUT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGO initiated at ioctl request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fcio_logout(port, job->job_private, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_GETMAP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_GETMAP_PLOGI_ALL: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = port->fp_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = FP_TASK_GETMAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_get_loopmap(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_portmap_t **)job->job_private,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t *)job->job_arg, 1, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = fp_ns_getmap(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, (fc_portmap_t **)job->job_private,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t *)job->job_arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_GAN_START_ID);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_portmap_t **)job->job_private,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t *)job->job_arg, 1, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_OFFLINE: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_port_event(port, ESC_SUNFC_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = port->fp_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = FP_TASK_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_port_offline(port, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_port_offline(port, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_STARTUP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fp_port_startup(port, job)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, rval),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Topology discovery failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Attempt building device handles in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of private Loop.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_topology == FC_TOP_PRIVATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_get_loopmap(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_lilp_map.lilp_magic < MAGIC_LIRP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_total_devices == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hack to avoid state changes going up early
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fabric_online(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags &= ~JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PORT_ONLINE: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char *newtop;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char *oldtop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old_top;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_port_event(port, ESC_SUNFC_PORT_ONLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bail out early if there are a lot of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state changes in the pipeline
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_statec_busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (old_top = port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop = "Private Loop";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop = "Public Loop";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop = "Point to Point";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop = "Fabric";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = port->fp_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = FP_TASK_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fp_port_startup(port, job)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_statec_busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_state = FC_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, rval),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Topology discovery failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_offline_tid == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout(fp_offline_timeout,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)port, fp_offline_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newtop = "Private Loop";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newtop = "Public Loop";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newtop = "Point to Point";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newtop = "Fabric";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newtop = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (oldtop && newtop && strcmp(oldtop, newtop)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Change in FC Topology old = %s new = %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldtop, newtop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int orphan = (old_top == FC_TOP_FABRIC ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_top == FC_TOP_PUBLIC_LOOP) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_loop_online(port, job, orphan);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fabric_online(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_p2p_online(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Watch curiously at what the next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state transition can do.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Topology Unknown, Offlining the port..");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_state = FC_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_offline_tid == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout(fp_offline_timeout,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)port, fp_offline_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_PLOGI_GROUP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_plogi_group(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_UNSOL_REQUEST: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_buf(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_unsol_buf_t *)job->job_private, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_NS_CMD: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = (fctl_ns_req_t *)job->job_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_code < NS_GA_NXT ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code > NS_DA_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_BADCMD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_CMD_A_REG(ns_cmd->ns_cmd_code)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_BADOBJECT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_reg(port, ns_cmd->ns_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code, job, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case JOB_LINK_RESET: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = (la_wwn_t *)job->job_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pwwn != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte topology = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_is_wwn_zero(pwwn) == FC_SUCCESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte topology == FC_TOP_PRIVATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_LINK_RESET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_remote_lip(port, pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_BADCMD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform FC port bring up initialization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_port_startup(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t src_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_lilpmap_t *lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(2, 0), "Entering fp_port_startup;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " port=%p, job=%p", port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = FC_PORT_STATE_MASK(port->fp_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_type.port_type = FC_NS_PORT_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == FC_STATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_type.port_type = FC_NS_PORT_NL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map = &port->fp_lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fp_get_lilpmap(port, lilp_map)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, rval),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "LILP map Invalid or not present");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lilp_map->lilp_length == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_NO_MAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "LILP map length zero");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NO_MAP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id = lilp_map->lilp_myalpa & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_p2p_info_t p2p_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pd_recepient;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get P2P remote port info if possible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_P2P_INFO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = sizeof (fc_fca_p2p_info_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = (caddr_t)&p2p_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id = p2p_info.fca_d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_type.port_type = FC_NS_PORT_N;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_PT_PT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_recepient = fctl_wwn_cmp(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &port->fp_service_params.nport_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &p2p_info.pwwn) < 0 ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_RECEPIENT : PD_PLOGI_INITIATOR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_create_remote_port(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &p2p_info.nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &p2p_info.pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p2p_info.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_recepient, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(2, 0), "Exiting fp_port_startup;"
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China " P2P port=%p pd=%p fp %x pd %x", port, pd,
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, p2p_info.d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_type.port_type = FC_NS_PORT_N;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = fp_fabric_login(port, src_id, job, FP_CMD_PLOGI_DONT_CARE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_type.port_type = FC_NS_PORT_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy <= 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, rval, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Couldn't transport FLOGI");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ns_init(port, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == FC_STATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_PRIVATE_LOOP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_lilp_map.lilp_myalpa & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(2, 0), "Exiting fp_port_startup; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform ULP invocations following FC port startup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_startup_done(opaque_t arg, uchar_t result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_attach_ulps(port, FC_CMD_ATTACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(2, 0), "fp_startup almost complete; port=%p", port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform ULP port attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ulp_port_attach(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_soft_attach_t *att = (fp_soft_attach_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = att->att_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(1, 0), "port attach of"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ULPs begin; port=%p, cmd=%x", port, att->att_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_attach_ulps(att->att_port, att->att_cmd, &modlinkage);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (att->att_need_pm_idle == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_DTRACE(FP_NHEAD1(1, 0), "port attach of"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ULPs end; port=%p, cmd=%x", port, att->att_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&att->att_port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att->att_port->fp_ulp_attach = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_task = port->fp_last_task;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_task = FP_TASK_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&att->att_port->fp_attach_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&att->att_port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(att, sizeof (fp_soft_attach_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Entry point to funnel all requests down to FCAs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_sendcmd(fc_local_port_t *port, fp_cmd_t *cmd, opaque_t fca_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1 || (cmd->cmd_ulp_pkt != NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_statec_busy || FC_PORT_STATE_MASK(port->fp_state) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_STATE_OFFLINE))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This means there is more than one state change
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at this point of time - Since they are processed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * serially, any processing of the current one should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be failed, failed and move up in processing the next
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state = FC_PKT_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_job) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A state change that is going to be invalidated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by another one already in the port driver's queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * need not go up to all ULPs. This will minimize
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * needless processing and ripples in ULP modules
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_STATEC_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state = FC_PKT_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = cmd->cmd_transport(fca_handle, &cmd->cmd_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_TRAN_BUSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_interval = fp_retry_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_retry_cmd(&cmd->cmd_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state = FC_PKT_TRAN_BSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds++;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Each time a timeout kicks in, walk the wait queue, decrement the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the retry_interval, when the retry_interval becomes less than
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or equal to zero, re-transport the command: If the re-transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fails with BUSY, enqueue the command in the wait queue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In order to prevent looping forever because of commands enqueued
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from within this function itself, save the current tail pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (in cur_tail) and exit the loop after serving this command.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_resendcmd(void *port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cur_tail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cur_tail = port->fp_wait_tail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((cmd = fp_deque_cmd(port)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_interval -= fp_retry_ticker;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we are detaching */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_DETACH_INPROGRESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state = FC_PKT_TRAN_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_retry_interval <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = cmd->cmd_transport(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &cmd->cmd_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_pkt.pkt_state == FC_PKT_TRAN_BSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--cmd->cmd_retry_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_enque_cmd(port, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == cur_tail) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TRAN_BSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_state =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TRAN_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds++;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_enque_cmd(port, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == cur_tail) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = timeout(fp_resendcmd, (caddr_t)port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_retry_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle Local, Fabric, N_Port, Transport (whatever that means) BUSY here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * Yes, as you can see below, cmd_retry_count is used here too. That means
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the retries for BUSY are less if there were transport failures (transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failure means fca_transport failure). The goal is not to exceed overall
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * retries set in the cmd_retry_count (whatever may be the reason for retry)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Values:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_retry_cmd(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--cmd->cmd_retry_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_enque_cmd(cmd->cmd_port, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Queue up FC packet for deferred retry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_enque_cmd(fc_local_port_t *port, fp_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, &cmd->cmd_pkt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Retrying ELS for %x", cmd->cmd_pkt.pkt_cmd_fhdr.d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_tail) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tail->cmd_next = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tail = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_wait_head == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_head = port->fp_wait_tail = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_tid == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = timeout(fp_resendcmd, (caddr_t)port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_retry_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle all RJT codes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_reject(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t next_class;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada port = cmd->cmd_port;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada switch (pkt->pkt_state) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_FABRIC_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_NPORT_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada if (pkt->pkt_reason == FC_REASON_CLASS_NOT_SUPP) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada next_class = fp_get_nextclass(cmd->cmd_port,
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada FC_TRAN_CLASS(pkt->pkt_tran_flags));
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada if (next_class == FC_TRAN_CLASS_INVALID) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada return (rval);
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada }
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada pkt->pkt_tran_flags = FC_TRAN_INTR | next_class;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada pkt->pkt_tran_type = FC_PKT_EXCHANGE;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada rval = fp_sendcmd(cmd->cmd_port, cmd,
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada cmd->cmd_port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada if (rval != FC_SUCCESS) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada pkt->pkt_state = FC_PKT_TRAN_ERROR;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada }
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_LS_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_BA_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada if ((pkt->pkt_reason == FC_REASON_LOGICAL_ERROR) ||
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada (pkt->pkt_reason == FC_REASON_LOGICAL_BSY)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_interval = fp_retry_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_retry_cmd(pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_FS_RJT:
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China if ((pkt->pkt_reason == FC_REASON_FS_LOGICAL_BUSY) ||
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China ((pkt->pkt_reason == FC_REASON_FS_CMD_UNABLE) &&
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China (pkt->pkt_expln == 0x00))) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada cmd->cmd_retry_interval = fp_retry_delay;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada rval = fp_retry_cmd(pkt);
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada }
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_LOCAL_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada if (pkt->pkt_reason == FC_REASON_QFULL) {
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada cmd->cmd_retry_interval = fp_retry_delay;
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada rval = fp_retry_cmd(pkt);
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada }
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada default:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada FP_TRACE(FP_NHEAD1(1, 0),
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada "fp_handle_reject(): Invalid pkt_state");
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return the next class of service supported by the FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uchar_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_get_nextclass(fc_local_port_t *port, uchar_t cur_class)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t next_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cur_class) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS_INVALID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_cos & FC_NS_CLASS1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_class = FC_TRAN_CLASS1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS1:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_cos & FC_NS_CLASS2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_class = FC_TRAN_CLASS2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS2:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_cos & FC_NS_CLASS3) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_class = FC_TRAN_CLASS3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS3:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_class = FC_TRAN_CLASS_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (next_class);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if a class of service is supported by the FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_is_class_supported(uint32_t cos, uchar_t tran_class)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (tran_class) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS1:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cos & FC_NS_CLASS1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS2:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cos & FC_NS_CLASS2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRAN_CLASS3:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cos & FC_NS_CLASS3) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dequeue FC packet for retry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fp_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_deque_cmd(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To avoid races, NULL the fp_wait_tid as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are about to exit the timeout thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = port->fp_wait_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_head = cmd->cmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for job completion
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_jobwait(job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_p(&job->job_port_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Convert FC packet state to FC errno
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_state_to_rval(uchar_t state)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (fp_xlat) /
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (fp_xlat[0]); count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_xlat[count].xlat_state == state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fp_xlat[count].xlat_rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For Synchronous I/O requests, the caller is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * expected to do fctl_jobdone(if necessary)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We want to preserve at least one failure in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * job_result if it happens.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_iodone(fp_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *ulp_pkt = cmd->cmd_ulp_pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job = cmd->cmd_job;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd = cmd->cmd_pkt.pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(&cmd->cmd_pkt != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = fp_state_to_rval(cmd->cmd_pkt.pkt_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd && cmd->cmd_flags & FP_CMD_DELDEV_ON_ERROR &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_IS_PKT_ERROR(ulp_pkt)) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(node != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_destroy_remote_port(port, pd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Job completion handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_jobdone(job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_counter > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--job->job_counter != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_ulp_pkts) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_ulp_listlen > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(job->job_ulp_pkts,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_packet_t *) * job->job_ulp_listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_flags & JOB_TYPE_FP_ASYNC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_v(&job->job_port_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to perform shutdown of a port during a detach. No return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value since the detach should not fail because the port shutdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * failed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_port_shutdown(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed struct pwwn_hash *head;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_taskq) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We must release the mutex here to ensure that other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * potential jobs can complete their processing. Many
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * also need this mutex.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte taskq_wait(port->fp_taskq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_offline_tid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = port->fp_offline_tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_wait_tid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = port->fp_wait_tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_wait_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * While we cancel the timeout, let's also return the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the outstanding requests back to the callers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((cmd = fp_deque_cmd(port)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job->job_result = FC_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Gracefully LOGO with all the devices logged in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_flags & JOB_TYPE_FP_ASYNC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = job->job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags &= ~JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_login_count > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Force the counter to ONE in order
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for us to really send LOGO els.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_logout(port, pd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Can't logout all devices. Proceeding with"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " port shutdown");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_all_remote_ports(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ns_fini(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flags) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags = flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build the port driver's data structures based on the AL_PA list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_get_loopmap(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_lilpmap_t *lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_lilp_map.lilp_length == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_NO_MAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map = &port->fp_lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = lilp_map->lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_code == JOB_PORT_GETMAP_PLOGI_ALL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag = FP_CMD_PLOGI_RETAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag = FP_CMD_PLOGI_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < lilp_map->lilp_length; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = lilp_map->lilp_alpalist[count];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d_id == (lilp_map->lilp_myalpa & 0xFF)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flag == FP_CMD_PLOGI_DONT_CARE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, d_id, job, flag,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform loop ONLINE processing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_loop_online(fc_local_port_t *port, job_request_t *job, int orphan)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_lilpmap_t *lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_loop_online begin; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map = &port->fp_lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lilp_map->lilp_length) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_IN_FCA_RESET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_FCA_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(PLDA_RR_TOV * 1000 * 1000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = lilp_map->lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < lilp_map->lilp_length; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = lilp_map->lilp_alpalist[count];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d_id == (lilp_map->lilp_myalpa & 0xFF)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_recepient == PD_PLOGI_INITIATOR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_type != PORT_DEVICE_OLD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_DONT_CARE, KM_SLEEP, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_statec_busy > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port, &changelist, &listlen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, 0, orphan);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_lilp_map.lilp_magic < MAGIC_LIRP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_total_devices == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = port->fp_dev_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_statec_cb(port, FC_STATE_ONLINE, changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen, listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(changelist == NULL && listlen == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_loop_online end; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get an Arbitrated Loop map from the underlying FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_get_lilpmap(fc_local_port_t *port, fc_lilpmap_t *lilp_map)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_get_lilpmap Begin; port=%p, map=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, lilp_map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)lilp_map, sizeof (fc_lilpmap_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_getmap(port->fp_fca_handle, lilp_map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map->lilp_magic &= 0xFF; /* Ignore upper byte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_NO_MAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (lilp_map->lilp_length == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (lilp_map->lilp_magic >= MAGIC_LISM &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map->lilp_magic < MAGIC_LIRP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since the map length is zero, provide all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the valid AL_PAs for NL_ports discovery.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_length = sizeof (fp_valid_alpas) /
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fp_valid_alpas[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map->lilp_length = lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fp_valid_alpas, lilp_map->lilp_alpalist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_validate_lilp_map(lilp_map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = lilp_map->lilp_length - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS && !(port->fp_soft_state & FP_SOFT_BAD_LINK)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_BAD_LINK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_fca_tran->fca_reset(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_FCA_RESET_CORE) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "FCA reset failed after LILP map was found"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " to be invalid");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_BAD_LINK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_get_lilpmap End; port=%p, map=%p", port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform Fabric Login:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Values:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_NOMEM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_TRANSPORT_ERROR
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and a lot others defined in fc_error.h
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fabric_login(fc_local_port_t *port, uint32_t s_id, job_request_t *job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uchar_t class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_fabric_login Begin; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = fp_get_nextclass(port, FC_TRAN_CLASS_INVALID);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (class == FC_TRAN_CLASS_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_ELS_BAD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_xlogi_init(port, cmd, s_id, 0xFFFFFE, fp_flogi_intr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, LA_ELS_FLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_fabric_login End; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In some scenarios such as private loop device discovery period
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_remote_port_t data structure isn't allocated. The allocation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is done when the PLOGI is successful. In some other scenarios
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * such as Fabric topology, the fc_remote_port_t is already created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and initialized with appropriate values (as the NS provides
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * them)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_port_login(fc_local_port_t *port, uint32_t d_id, job_request_t *job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cmd_flag, int sleep, fc_remote_port_t *pd, fc_packet_t *ulp_pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int relogin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int found = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_get_remote_port_by_did(port, d_id) == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_counter > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = fp_get_nextclass(port, FC_TRAN_CLASS_INVALID);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (class == FC_TRAN_CLASS_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_ELS_BAD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_lookup_pd_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte relogin = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((tmp_pd->pd_aux_flags & PD_DISABLE_RELOGIN) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(tmp_pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd->pd_state = PORT_DEVICE_LOGGED_IN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte relogin = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!relogin) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_flag |= FP_CMD_PLOGI_RETAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_adisc_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_adisc_t), sleep, tmp_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = cmd_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = ulp_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_adisc_init(cmd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_adisc_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = sizeof (la_els_adisc_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t), sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = cmd_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = ulp_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_xlogi_init(port, cmd, src_id, d_id, fp_plogi_intr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, LA_ELS_PLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* npiv check to make sure we don't log into ourself */
4e4ff2425536355e598306a9d27a700e0fad5013Yu Renia Miao if (relogin &&
4e4ff2425536355e598306a9d27a700e0fad5013Yu Renia Miao ((port->fp_npiv_type == FC_NPIV_PORT) ||
4e4ff2425536355e598306a9d27a700e0fad5013Yu Renia Miao (port->fp_npiv_flag == FC_NPIV_ENABLE))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((d_id & 0xffff00) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_port_id.port_id & 0xffff00)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte found = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (found ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (found) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_NPORT_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = pkt->pkt_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_reason = pkt->pkt_reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_action = pkt->pkt_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_expln = pkt->pkt_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register the LOGIN parameters with a port device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_register_login(ddi_acc_handle_t *handle, fc_remote_port_t *pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t *acc, uchar_t class)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_login_count == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (handle) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_csp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->common_service,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (acc->common_service), DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->class_1, sizeof (acc->class_1),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp2,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->class_2, sizeof (acc->class_2),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)&pd->pd_clsp3,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->class_3, sizeof (acc->class_3),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_csp = acc->common_service;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_clsp1 = acc->class_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_clsp2 = acc->class_2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_clsp3 = acc->class_3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_LOGGED_IN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_class = class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_get_remote_port_by_did(pd->pd_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id) == pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (handle) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(pd->pd_port, *handle, (uint8_t *)node->fd_vv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)acc->vendor_version, sizeof (node->fd_vv),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(acc->vendor_version, node->fd_vv, sizeof (node->fd_vv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the remote port as OFFLINE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_remote_port_offline(fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_login_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((pd->pd_aux_flags & PD_DISABLE_RELOGIN) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_csp, sizeof (struct common_service));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp1, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp2, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp3, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_class = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_reset(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deregistration of a port device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_unregister_login(fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_csp, sizeof (struct common_service));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp1, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp2, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pd->pd_clsp3, sizeof (struct service_param));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_class = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(node->fd_vv, sizeof (node->fd_vv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle OFFLINE state of an FCA port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_port_offline(fc_local_port_t *port, int notify)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int statec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed struct pwwn_hash *head;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_remote_port_offline(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte statec = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (notify) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decrement the statec busy counter as we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are almost done with handling the state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * change
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_statec_busy > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_statec_cb(port, FC_STATE_OFFLINE, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte statec++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte statec++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((tid = port->fp_offline_tid) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!statec) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = timeout(fp_offline_timeout,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)port, fp_offline_ticks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Offline devices and send up a state change notification to ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_offline_timeout(void *port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen = 0;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portmap_t *changelist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((FC_PORT_STATE_MASK(port->fp_state) != FC_STATE_OFFLINE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_SOFT_SUSPEND | FP_SOFT_POWER_DOWN)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count == 0 || port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0), "OFFLINE timeout");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_options & FP_CORE_ON_OFFLINE_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = port->fp_fca_tran->fca_reset(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_FCA_CORE)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, ret),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Failed to force adapter dump");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Forced adapter dump successfully");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (port->fp_options & FP_RESET_CORE_ON_OFFLINE_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = port->fp_fca_tran->fca_reset(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_FCA_RESET_CORE)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, ret),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Failed to force adapter dump and reset");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Forced adapter dump and reset successfully");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port, &changelist, &listlen, 1, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_statec_cb(port, FC_STATE_OFFLINE, changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen, listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform general purpose ELS request initialization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_els_init(fp_cmd_t *cmd, uint32_t s_id, uint32_t d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void (*comp) (), job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.d_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.s_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_comp = comp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_timeout = FP_ELS_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize PLOGI/FLOGI ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_xlogi_init(fc_local_port_t *port, fp_cmd_t *cmd, uint32_t s_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id, void (*intr) (), job_request_t *job, uchar_t ls_code)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, s_id, d_id, intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code = ls_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, cmd->cmd_pkt.pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&port->fp_service_params,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)cmd->cmd_pkt.pkt_cmd, sizeof (port->fp_service_params),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, cmd->cmd_pkt.pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)cmd->cmd_pkt.pkt_cmd, sizeof (payload),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize LOGO ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_logo_init(fc_remote_port_t *pd, fp_cmd_t *cmd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logo_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, port->fp_port_id.port_id, pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logo_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_LOGO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_ww_name = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_id = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize RNID ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_rnid_init(fp_cmd_t *cmd, uint16_t flag, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_rnid_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, port->fp_port_id.port_id, pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_rnid_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_RNID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.data_format = flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize RLS ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_rls_init(fp_cmd_t *cmd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_rls_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, port->fp_port_id.port_id, pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_rls_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_RLS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.rls_portid = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize an ADISC ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_adisc_init(fp_cmd_t *cmd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_adisc_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, port->fp_port_id.port_id, pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_adisc_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_ADISC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_id = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.port_wwn = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.node_wwn = port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.hard_addr = port->fp_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send up a state change notification to ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Spawns a call to fctl_ulp_statec_cb in a taskq thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ulp_statec_cb(fc_local_port_t *port, uint32_t state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist, uint32_t listlen, uint32_t alloc_len, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_clist_t *clist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist = kmem_zalloc(sizeof (*clist), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(changelist, alloc_len * sizeof (*changelist));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_state = state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_flags = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_port = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_len = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_size = alloc_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map = changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bump the reference count of each fc_remote_port_t in this changelist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is necessary since these devices will be sitting in a taskq
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and referenced later. When the state change notification is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * complete, the reference counts will be decremented.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < clist->clist_len; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = clist->clist_map[count].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((pd->pd_ref_count >= 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_aux_flags & PD_GIVEN_TO_ULPS));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_state !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_GIVEN_TO_ULPS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sanity check for presence of OLD devices in the hash lists
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(clist->clist_map != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < clist->clist_len; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t pwwn;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portid_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = clist->clist_map[count].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != clist->clist_map[count].map_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != clist->clist_map[count].map_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == FC_STATE_ONLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) taskq_dispatch(port->fp_taskq, fctl_ulp_statec_cb,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(4, 0), "fp_ulp_statec fired; Port=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "state=%x, len=%d", port, state, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send up a FC_STATE_DEVICE_CHANGE state notification to ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ulp_devc_cb(fc_local_port_t *port, fc_portmap_t *changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen, uint32_t alloc_len, int sleep, int sync)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_clist_t *clist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist = kmem_zalloc(sizeof (*clist), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(changelist, alloc_len * sizeof (*changelist));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_state = FC_STATE_DEVICE_CHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_flags = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_port = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_len = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_size = alloc_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map = changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Send sysevents for target state changes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_size) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(clist->clist_map != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < clist->clist_len; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = clist->clist_map[count].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bump reference counts on all fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structs in this list. We don't know when the task
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will fire, and we don't need these fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structs going away behind our back.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((pd->pd_ref_count >= 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_aux_flags & PD_GIVEN_TO_ULPS));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_VALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_type ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_NEW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update our state change counter */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_change++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Additions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_target_event(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ESC_SUNFC_TARGET_ADD,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map[count].map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map[count].map_did.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((clist->clist_map[count].map_type ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_OLD) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (clist->clist_map[count].map_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update our state change counter */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_last_change++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For removals, we don't decrement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd_ref_count until after the ULP's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state change callback function has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * completed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Removals */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_log_target_event(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ESC_SUNFC_TARGET_REMOVE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map[count].map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map[count].map_did.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_state !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Indicate that the ULPs are now aware of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_GIVEN_TO_ULPS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sanity check for OLD devices in the hash lists
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd && clist->clist_map[count].map_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t pwwn;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portid_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This overwrites the 'pd' local variable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Beware of this if 'pd' ever gets
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * referenced below this block.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != clist->clist_map[count].map_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != clist->clist_map[count].map_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sync) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_wait = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&clist->clist_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&clist->clist_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = taskq_dispatch(port->fp_taskq, fctl_ulp_statec_cb, clist, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sync && ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (clist->clist_wait) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&clist->clist_cv, &clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&clist->clist_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(clist, sizeof (*clist));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(4, 0), "fp_ulp_devc dispatch failed; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port=%p", port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(clist->clist_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*(clist->clist_map)) * clist->clist_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(clist, sizeof (*clist));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(4, 0), "fp_ulp_devc fired; port=%p, len=%d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, listlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform PLOGI to the group of devices for ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_plogi_group(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int offline;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *ulp_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t *els_data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t ls_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_plogi_group begin; port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = job->job_ulp_listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = job->job_ulp_listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offline = (port->fp_statec_busy ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < listlen; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_ulp_pkts[count]->pkt_rsplen >=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt = job->job_ulp_pkts[count];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = ulp_pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = ulp_pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (offline) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts[count] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (pd == NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed /* reset later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags == PD_ELS_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts[count] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ulp_pkt->pkt_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_ELS_IN_PROGRESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHRU */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_LOCAL_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts[count] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Validate the pd corresponding to the d_id passed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((tmp_pd == NULL) || (pd != tmp_pd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_reason = FC_REASON_NO_CONNECTION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts[count] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_group contd; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port=%p, pd=%p", port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els_data = (la_els_logi_t *)ulp_pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code.ls_code = LA_ELS_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&ls_code, (uint8_t *)&els_data->ls_code,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ls_code_t), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&pd->pd_csp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&els_data->common_service,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_csp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&pd->pd_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&els_data->nport_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_port_name), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&pd->pd_clsp1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&els_data->class_1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_clsp1), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&pd->pd_clsp2,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&els_data->class_2,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_clsp2), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&pd->pd_clsp3,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&els_data->class_3,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_clsp3), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&node->fd_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(&els_data->node_ww_name),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (node->fd_node_name), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(pd->pd_port, ulp_pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&node->fd_vv,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(&els_data->vendor_version),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (node->fd_vv), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_FAILURE; /* reset later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_pkt->pkt_state != FC_PKT_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts[count] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (done == listlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = listlen - done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < listlen; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ulp_pkt = job->job_ulp_pkts[count]) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ulp_pkt->pkt_state == FC_PKT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_flags = FP_CMD_PLOGI_RETAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = ulp_pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(d_id != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel /*
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel * We need to properly adjust the port device
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel * reference counter before we assign the pd
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel * to the ULP packets port device pointer.
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel */
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel if (pd != NULL && ulp_pkt->pkt_pd == NULL) {
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_enter(&pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel pd->pd_ref_count++;
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_exit(&pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel FP_TRACE(FP_NHEAD1(3, 0),
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel "fp_plogi_group: DID = 0x%x using new pd %p \
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel old pd NULL\n", d_id, pd);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel } else if (pd != NULL && ulp_pkt->pkt_pd != NULL &&
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel ulp_pkt->pkt_pd != pd) {
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_enter(&pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel pd->pd_ref_count++;
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_exit(&pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_enter(&ulp_pkt->pkt_pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel ulp_pkt->pkt_pd->pd_ref_count--;
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_exit(&ulp_pkt->pkt_pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel FP_TRACE(FP_NHEAD1(3, 0),
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel "fp_plogi_group: DID = 0x%x pkt_pd %p != pd %p\n",
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel d_id, ulp_pkt->pkt_pd, pd);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel } else if (pd == NULL && ulp_pkt->pkt_pd != NULL) {
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_enter(&ulp_pkt->pkt_pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel ulp_pkt->pkt_pd->pd_ref_count--;
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel mutex_exit(&ulp_pkt->pkt_pd->pd_mutex);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel FP_TRACE(FP_NHEAD1(3, 0),
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel "fp_plogi_group: DID = 0x%x pd is NULL and \
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel pkt_pd = %p\n", d_id, ulp_pkt->pkt_pd);
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel }
d03f60a0e569a43de9a720f5f0b4003d4d1dca0dZach Kissel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = ulp_pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In the Fabric topology, use NS to create
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port device, and if that fails still try
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with PLOGI - which will make yet another
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attempt to create after successful PLOGI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fp_create_remote_port_by_ns(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_flags |= FP_CMD_DELDEV_ON_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_plogi_group;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " NS created PD port=%p, job=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pd=%p", port, job, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ulp_pkt->pkt_pd == NULL) && (pd != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_plogi_group;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ulp_pkt's pd is NULL, get a pd %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, d_id, job, cmd_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, pd, ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_STATEC_BUSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_flags & FP_CMD_DELDEV_ON_ERROR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_group: NS created,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " PD removed; port=%p, job=%p", port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(node != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_destroy_remote_port(port, pd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_pkt->pkt_comp(ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_plogi_group end: port=%p, job=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Name server request initialization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_init(fc_local_port_t *port, job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, 0xFFFFFC, job, FP_CMD_PLOGI_RETAIN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, NULL, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_NO_NS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_NO_NS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this time, we'll do NS registration for objects in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ns_reg_cmds (see top of this file) array.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Each time a ULP module registers with the transport, the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appropriate fc4 bit is set fc4 types and registered with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the NS for this support. Also, ULPs and FC admin utilities
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * may do registration for objects like IP address, symbolic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port/node name, Initial process associator at run time.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = sizeof (ns_reg_cmds) / sizeof (ns_reg_cmds[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < size; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_ns_reg(port, NULL, ns_reg_cmds[count],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, 0, sleep) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ns_get_devcount(port, job, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_dev_count < FP_MAX_DEVICES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ns_get_devcount(port, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_ns_scr(port, job, FC_SCR_FULL_REGISTRATION,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Name server finish:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unregister for RSCNs
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * Unregister all the host port objects in the Name Server
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * Perform LOGO with the NS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_fini(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logo_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_ns_scr(port, job, FC_SCR_CLEAR_REGISTRATION, KM_SLEEP) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_ns_reg(port, NULL, NS_DA_ID, job, 0, KM_SLEEP) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logo_t),
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed FP_PORT_IDENTIFIER_LEN, KM_SLEEP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port->fp_ns_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_id = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_PLOGI_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_npiv_type == FC_NPIV_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, s_id, 0xFFFFFE, fp_logo_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, s_id, 0xFFFFFC, fp_logo_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_LOGO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_ww_name = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NS Registration function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It should be seriously noted that FC-GS-2 currently doesn't support
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an Object Registration by a D_ID other than the owner of the object.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * What we are aiming at currently is to at least allow Symbolic Node/Port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Name registration for any N_Port Identifier by the host software.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Anyway, if the second argument (fc_remote_port_t *) is NULL, this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function treats the request as Host NS Object.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_reg(fc_local_port_t *port, fc_remote_port_t *pd, uint16_t cmd_code,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int polled, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t s_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (polled) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd_code) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RPN_ID:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RNN_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rxn_req_t rxn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_rxn_req_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rxn.rxn_xname = ((cmd_code == NS_RPN_ID) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_service_params.nport_ww_name) :
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (port->fp_service_params.node_ww_name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_code == NS_RPN_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rxn.rxn_xname = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rxn.rxn_xname = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rxn.rxn_port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rxn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rxn), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RCS_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rcos_t rcos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_rcos_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcos.rcos_cos = port->fp_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcos.rcos_cos = pd->pd_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcos.rcos_port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rcos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rcos), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RFT_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rfc_type_t rfc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_rfc_type_t), sizeof (fc_reg_resp_t), sleep,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_fc4_types, rfc.rfc_types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_fc4_types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pd->pd_fc4types, rfc.rfc_types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rfc.rfc_port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rfc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rfc), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSPN_ID: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uchar_t name_len;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int pl_size;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portid_t spn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name_len = port->fp_sym_port_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name_len = pd->pd_spn_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pl_size = sizeof (fc_portid_t) + name_len + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) + pl_size,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spn = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&spn, (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pkt->pkt_cmd + sizeof (fc_ct_header_t)), sizeof (spn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&name_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte + sizeof (fc_portid_t)), 1, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)port->fp_sym_port_name, (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pkt->pkt_cmd + sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (spn) + 1), name_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint8_t *)pd->pd_spn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (spn) + 1), name_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RPT_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rpt_t rpt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_rpt_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rpt.rpt_type = port->fp_port_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rpt.rpt_type = pd->pd_porttype;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rpt.rpt_port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rpt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rpt), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RIP_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rip_t rip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_rip_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rip.rip_node_name =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_ip_addr, rip.rip_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_ip_addr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The most correct implementation should have the IP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * address in the fc_remote_node_t structure; I believe
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Node WWN and IP address should have one to one
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * correlation (but guess what this is changing in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC-GS-2 latest draft)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pd->pd_ip_addr, rip.rip_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_ip_addr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rip.rip_node_name = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rip), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RIPA_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_ipa_t ipa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_ipa_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipa.ipa_node_name =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_ipa, ipa.ipa_value,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_ipa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipa.ipa_node_name = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(node->fd_ipa, ipa.ipa_value,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (node->fd_ipa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&ipa,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ipa), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSNN_NN: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uchar_t name_len;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int pl_size;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name_len = port->fp_sym_node_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name_len = node->fd_snn_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pl_size = sizeof (la_wwn_t) + name_len + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pl_size, sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.node_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &snn, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)port->fp_sym_node_name, (uint8_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pkt->pkt_cmd + sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (snn) + 1), name_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(node != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)node->fd_snn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (snn) + 1), name_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&snn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (snn), DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&name_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte + sizeof (fc_ct_header_t) + sizeof (snn)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_DA_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_remall_t rall;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char tmp[4] = {0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_remall_t), sizeof (fc_reg_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, NULL, cmd_code, NULL, 0, 0, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ptr = (char *)(&s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp[3] = *ptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp[2] = *ptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp[1] = *ptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp[0] = *ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if defined(_BIT_FIELDS_LTOH)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)tmp, (caddr_t)(&rall.rem_port_id), 4);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rall.rem_port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&rall,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rall), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (polled) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common interrupt handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_common_intr(fc_packet_t *pkt, int iodone)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fail fast the upper layer requests if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a state change has occurred amidst.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt != NULL && port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_state = FC_PKT_PORT_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_reason = FC_REASON_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (!(port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_DETACH_INPROGRESS))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (pkt->pkt_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_LOCAL_BSY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_FABRIC_BSY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_NPORT_BSY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_TIMEOUT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_interval = (pkt->pkt_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TIMEOUT) ? 0 : fp_retry_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_retry_cmd(pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_FABRIC_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_NPORT_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_LOCAL_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_LS_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_PKT_FS_RJT:
e20df668c56beda452ed1ddd9da1cb7a99a8e51cRaghuram Prahlada case FC_PKT_BA_RJT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_handle_reject(pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_resid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_interval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_retry_cmd(pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS && iodone) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some not so long winding theory on point to point topology:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In the ACC payload, if the D_ID is ZERO and the common service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameters indicate N_Port, then the topology is POINT TO POINT.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In a point to point topology with an N_Port, during Fabric Login,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the destination N_Port will check with our WWN and decide if it
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * needs to issue PLOGI or not. That means, FLOGI could potentially
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * trigger an unsolicited PLOGI from an N_Port. The Unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI creates the device handles.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assuming that the host port WWN is greater than the other N_Port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN, then we become the master (be aware that this isn't the word
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * used in the FC standards) and initiate the PLOGI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_flogi_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int f_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *swwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t dwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logi_t *acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte com_svc_t csp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_flogi_intr; port=%p, pkt=%p, state=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, pkt, pkt->pkt_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Currently, we don't need to swap bytes here because qlc is faking the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * response for us and so endianness is getting taken care of. But we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have to fix this and generalize this at some point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte acc = (la_els_logi_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp, (uint8_t *)acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(resp.ls_code == LA_ELS_ACC);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&csp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->common_service, sizeof (csp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte f_port = FP_IS_F_PORT(csp.cmn_features) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = FC_PORT_STATE_MASK(port->fp_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (f_port == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (state != FC_STATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swwn = &port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&dwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->nport_ww_name, sizeof (la_wwn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->node_ww_name, sizeof (la_wwn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_PT_PT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(swwn, &dwwn) >= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ptpt_master = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let us choose 'X' as S_ID and 'Y'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as D_ID and that'll work; hopefully
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If not, it will get changed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_instance + FP_DEFAULT_SID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = port->fp_instance + FP_DEFAULT_DID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(1, 0), "fp_flogi_intr: fp %x"
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China "pd %x", port->fp_port_id.port_id, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_create_remote_port(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &nwwn, &dwwn, d_id, PD_PLOGI_INITIATOR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, NULL, "couldn't create device"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " d_id=%X", d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_tran_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = pkt->pkt_tran_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_PLOGI_RETAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_xlogi_init(port, cmd, s_id, d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_plogi_intr, cmd->cmd_job, LA_ELS_PLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (&cmd->cmd_pkt)->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We've just created this fc_remote_port_t, and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're about to use it to send a PLOGI, so
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * bump the reference count right now. When
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the packet is freed, the reference count will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be decremented. The ULP may also start using
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it, so mark it as given away as well.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_GIVEN_TO_ULPS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The device handles will be created when the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unsolicited PLOGI is completed successfully
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ptpt_master = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (f_port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == FC_STATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_PUBLIC_LOOP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology = FC_TOP_FABRIC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&port->fp_fabric_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->node_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id = pkt->pkt_resp_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle solicited PLOGI response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_plogi_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nl_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bailout;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t *acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nl_port = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_intr: port=%p, job=%p, d_id=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " jcount=%d pkt=%p, state=%x", port, cmd->cmd_job, d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job->job_counter, pkt, pkt->pkt_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bail out early on ULP initiated requests if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state change has occurred
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bailout = ((port->fp_statec_busy ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt) || bailout) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int skip_msg = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int giveup = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_state = pkt->pkt_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_reason = pkt->pkt_reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_action = pkt->pkt_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_expln = pkt->pkt_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an unsolicited cross login already created
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a device speed up the discovery by not retrying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the command mindlessly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd == NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_get_remote_port_by_did(port, d_id) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte giveup = (pkt->pkt_pd->pd_recepient ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_RECEPIENT) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (giveup) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This pd is marked as plogi
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * recipient, stop retrying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_plogi_intr: stop retry as"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " a cross login was accepted"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " from d_id=%x, port=%p.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_common_intr(pkt, 0) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = fctl_get_remote_port_by_did(port, d_id)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte skip_msg++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!bailout && !(skip_msg && port->fp_statec_busy) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy <= 1 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason != FC_REASON_FCAL_OPN_FAIL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In case of Login Collisions, JNI HBAs returns the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC pkt back to the Initiator with the state set to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_PKT_LS_RJT and reason to FC_REASON_LOGICAL_ERROR.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * QLC HBAs handles such cases in the FW and doesnot
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return the LS_RJT with Logical error when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * login collision happens.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pkt->pkt_state != FC_PKT_LS_RJT) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pkt->pkt_reason != FC_REASON_LOGICAL_ERROR)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, pkt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI to %x failed", d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI to %x failed. state=%x reason=%x.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, pkt->pkt_state, pkt->pkt_reason);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte acc = (la_els_logi_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp, (uint8_t *)acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(resp.ls_code == LA_ELS_ACC);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d_id == FS_NAME_SERVER || d_id == FS_FABRIC_CONTROLLER) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ns_login_class = FC_TRAN_CLASS(pkt->pkt_tran_flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(acc == (la_els_logi_t *)pkt->pkt_resp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->nport_ww_name, sizeof (la_wwn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->node_ww_name, sizeof (la_wwn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_is_wwn_zero(&pwwn) == FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_is_wwn_zero(&nwwn) == FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = pkt->pkt_pd) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
8eec3430a514cd7c4e568f6dbe40d81b2f8f2d27Rijawanemohammadhusen Nadaf FP_TRACE(FP_NHEAD2(1, 0), "fp_plogi_intr: fp %x pd %x",
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_create_remote_port(port, &nwwn, &pwwn, d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_INITIATOR, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "couldn't create port device handles"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " d_id=%x", d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_state == PORT_DEVICE_LOGGED_IN) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags |= FP_CMD_PLOGI_RETAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_port_id.port_id != d_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_aux_flags & PD_IN_DID_QUEUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Possible Duplicate name or address"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " identifiers in the PLOGI response"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " D_ID=%x, PWWN=%s: Please check the"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " configuration", d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_LOGGED_OUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd, *new_wwn_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_wwn_pd = fctl_get_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&pd->pd_port_name, &pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_intr: d_id=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pd_state=%x pd_type=%x", d_id, pd->pd_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_state == PORT_DEVICE_LOGGED_IN &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type == PORT_DEVICE_OLD) ||
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char old_name[17];
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char new_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, old_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pwwn, new_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_plogi_intr: PWWN of a device with D_ID=%x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "changed. New PWWN = %s, OLD PWWN = %s ; tmp_pd:%p "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pd:%p new_wwn_pd:%p, cmd_ulp_pkt:%p, bailout:0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, new_name, old_name, tmp_pd, pd, new_wwn_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt, bailout);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PWWN of a device with D_ID=%x changed."
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " New PWWN = %s, OLD PWWN = %s", d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_name, old_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt && !bailout) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int len = 1;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed /* # entries in changelist */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lets now check if there already is a pd with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this new WWN in the table. If so, we'll mark
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it as invalid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_wwn_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is another pd with in the pwwn
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table with the same WWN that we got
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the PLOGI payload. We have to get
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it out of the pwwn table, update the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd's state (fp_fillout_old_map does
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this for us) and add it to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * changelist that goes up to ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * len is length of changelist and so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * increment it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd != pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Odd case where pwwn and did
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tables are out of sync but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will handle that too. See
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * more comments below.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * One more device that ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should know about and so len
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * gets incremented again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = changelist = kmem_zalloc(len *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&new_wwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = new_wwn_pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&new_wwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hold the fd_mutex since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_copy_portmap_held expects it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Preserve lock hierarchy by grabbing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fd_mutex before pd_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&new_wwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map_held(listptr++,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_wwn_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&new_wwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Safety check :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lets ensure that the pwwn and did
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tables are in sync. Ideally, we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should not find that these two pd's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are different.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd != pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* As above grab fd_mutex */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map_held(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr++, tmp_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now add "pd" (not tmp_pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to fp_did_table to sync it up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with fp_pwwn_table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd->pd_mutex is already held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at this point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = changelist = kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(changelist != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_changed_map(listptr, pd, &d_id,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist, len,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed len, KM_NOSLEEP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_porttype.port_type == FC_NS_PORT_NL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nl_port = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (pd->pd_aux_flags & PD_DISABLE_RELOGIN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_LOGGED_OUT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_aux_flags & PD_IN_DID_QUEUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Possible Duplicate name or address"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " identifiers in the PLOGI response"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " D_ID=%x, PWWN=%s: Please check the"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " configuration", d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_LOGGED_OUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_register_login(&pkt->pkt_resp_acc, pd, acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_TRAN_CLASS(pkt->pkt_tran_flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_state = pkt->pkt_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_action = pkt->pkt_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_expln = pkt->pkt_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt->pkt_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_plogi_intr;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ulp_pkt's pd is NULL, get a pd %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&pkt->pkt_resp_fhdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&cmd->cmd_ulp_pkt->pkt_resp_fhdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_frame_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)pkt->pkt_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)cmd->cmd_ulp_pkt->pkt_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_topology == FC_TOP_PRIVATE_LOOP || nl_port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the fc_remote_port_t pointer is not set in the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_packet_t, then this fc_remote_port_t must have just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * been created. Save the pointer and also increment the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t reference count.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++; /* It's in use! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_adisc_init(cmd, cmd->cmd_job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmdlen = sizeof (la_els_adisc_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_rsplen = sizeof (la_els_adisc_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_flags & FP_CMD_PLOGI_RETAIN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logo_init(pd, cmd, cmd->cmd_job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmdlen = sizeof (la_els_logo_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_rsplen = FP_PORT_IDENTIFIER_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle solicited ADISC response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_adisc_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int bailout;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_cmd_t *cmd, *logi_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_adisc_t *acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hardaddr_t ha;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator, adiscfail = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_job && cmd->cmd_job->job_counter);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL && port != NULL && cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bailout = ((port->fp_statec_busy ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bailout) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_state == FC_PKT_SUCCESS && pkt->pkt_resp_resid == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte acc = (la_els_adisc_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)acc, sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp.ls_code == LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int is_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&ha,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->hard_addr, sizeof (ha),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte is_private =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_topology == FC_TOP_PRIVATE_LOOP) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_aux_flags & PD_IN_DID_QUEUE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type != PORT_DEVICE_NEW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (is_private && (pd->pd_hard_addr.hard_addr !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha.hard_addr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (is_private && (ha.hard_addr &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id != ha.hard_addr)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "NL_Port Identifier %x doesn't match"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " with Hard Address %x, Will use Port"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " WWN %s", pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha.hard_addr, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_hard_addr.hard_addr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_hard_addr.hard_addr = ha.hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_common_intr(pkt, 0) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_common_intr(pkt, 0) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy <= 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China if (pkt->pkt_state == FC_PKT_LS_RJT &&
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China pkt->pkt_reason == FC_REASON_CMD_UNABLE) {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China uchar_t class;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China int cmd_flag;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China uint32_t src_id;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China class = fp_get_nextclass(port,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China FC_TRAN_CLASS_INVALID);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China if (class == FC_TRAN_CLASS_INVALID) {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_iodone(cmd);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China return;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China }
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(1, 0), "ADISC re-login; "
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China "fp_state=0x%x, pkt_state=0x%x, "
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China "reason=0x%x, class=0x%x",
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China port->fp_state, pkt->pkt_state,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China pkt->pkt_reason, class);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China cmd_flag = FP_CMD_PLOGI_RETAIN;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
c465437abaf8cc10b6cafec2fc1576bc770537baallan logi_cmd = fp_alloc_pkt(port,
c465437abaf8cc10b6cafec2fc1576bc770537baallan sizeof (la_els_logi_t),
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China sizeof (la_els_logi_t), KM_SLEEP, pd);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China if (logi_cmd == NULL) {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_iodone(cmd);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China return;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China }
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
c465437abaf8cc10b6cafec2fc1576bc770537baallan logi_cmd->cmd_pkt.pkt_tran_flags =
c465437abaf8cc10b6cafec2fc1576bc770537baallan FC_TRAN_INTR | class;
c465437abaf8cc10b6cafec2fc1576bc770537baallan logi_cmd->cmd_pkt.pkt_tran_type =
c465437abaf8cc10b6cafec2fc1576bc770537baallan FC_PKT_EXCHANGE;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China logi_cmd->cmd_flags = cmd_flag;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China logi_cmd->cmd_retry_count = fp_retry_count;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China logi_cmd->cmd_ulp_pkt = NULL;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China mutex_enter(&port->fp_mutex);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China src_id = port->fp_port_id.port_id;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China mutex_exit(&port->fp_mutex);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_xlogi_init(port, logi_cmd, src_id,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China pkt->pkt_cmd_fhdr.d_id, fp_plogi_intr,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China cmd->cmd_job, LA_ELS_PLOGI);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China if (pd) {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China mutex_enter(&pd->pd_mutex);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China pd->pd_flags = PD_ELS_IN_PROGRESS;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China mutex_exit(&pd->pd_mutex);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China }
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China if (fp_sendcmd(port, logi_cmd,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China port->fp_fca_handle) == FC_SUCCESS) {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_free_pkt(cmd);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China return;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China } else {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_free_pkt(logi_cmd);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China }
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China } else {
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, pkt,
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China "ADISC to %x failed, cmd_flags=%x",
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China pkt->pkt_cmd_fhdr.d_id, cmd->cmd_flags);
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China cmd->cmd_flags &= ~FP_CMD_PLOGI_RETAIN;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China adiscfail = 1;
678fb48bf010b51ffc99ea50f032a7c947574249duo liu - Sun Microsystems - Beijing China }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_state = pkt->pkt_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_action = pkt->pkt_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_expln = pkt->pkt_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_ulp_pkt->pkt_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt->pkt_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_adisc__intr;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ulp_pkt's pd is NULL, get a pd %p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&pkt->pkt_resp_fhdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&cmd->cmd_ulp_pkt->pkt_resp_fhdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_frame_hdr_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)pkt->pkt_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)cmd->cmd_ulp_pkt->pkt_resp,
3bc3cf69284dcc842f5b10f4ac53b272a88b173aRaghuram Prahlada sizeof (la_els_adisc_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_flags & FP_CMD_PLOGI_RETAIN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_adisc_intr: Perform LOGO.cmd_flags=%x, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_retry_count=%x, ulp_pkt=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags, fp_retry_count, cmd->cmd_ulp_pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logo_init(pd, cmd, cmd->cmd_job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmdlen = sizeof (la_els_logo_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_rsplen = FP_PORT_IDENTIFIER_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (adiscfail) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ((pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_LOGGED_OUT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (pd->pd_aux_flags & PD_DISABLE_RELOGIN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NEW;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (initiator) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unregister_login(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(changelist, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(changelist, pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_adisc_intr: Dev change notification "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "to ULP port=%p, pd=%p, map_type=%x map_state=%x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "map_flags=%x initiator=%d", port, pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_type, changelist->map_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_flags, initiator);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, 1, KM_SLEEP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle solicited LOGO response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_logo_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_resp, sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(resp.ls_code == LA_ELS_ACC);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unregister_login(pkt->pkt_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(pkt->pkt_ulp_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle solicited RNID response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_rnid_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_rnid_acc_t *acc;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_resp, sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed cmd->cmd_port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = cmd->cmd_job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_private != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If failure or LS_RJT then retry the packet, if needed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS || resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Save node_id memory allocated in ioctl code */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte acc = (la_els_rnid_acc_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)job->job_private,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)acc, sizeof (la_els_rnid_acc_t), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* wakeup the ioctl thread and free the pkt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle solicited RLS response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_rls_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_rls_acc_t *acc;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_resp, sizeof (resp), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed cmd->cmd_port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = cmd->cmd_job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_private != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If failure or LS_RJT then retry the packet, if needed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt) || resp.ls_code != LA_ELS_ACC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Save link error status block in memory allocated in ioctl code */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte acc = (la_els_rls_acc_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)job->job_private,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&acc->rls_link_params, sizeof (fc_rls_acc_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* wakeup the ioctl thread and free the pkt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A solicited command completion interrupt (mostly for commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that require almost no post processing such as SCR ELS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(pkt->pkt_ulp_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle the underlying port's state change
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_statec_cb(opaque_t port_handle, uint32_t state)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If it is not possible to process the callbacks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just drop the callback on the floor; Don't bother
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do something that isn't safe at this time
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_SOFT_SUSPEND | FP_SOFT_POWER_DOWN)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FC_PORT_STATE_MASK(port->fp_state) == FC_PORT_STATE_MASK(state))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_soft_state & FP_SOFT_IN_STATEC_CB);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For now, force the trusted method of device authentication (by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI) when LIPs do not involve OFFLINE to ONLINE transition.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(state) == FC_STATE_LIP ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PORT_STATE_MASK(state) == FC_STATE_LIP_LBIT_SET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = FC_PORT_SPEED_MASK(port->fp_state) | FC_STATE_LOOP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_port_offline(port, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (FC_PORT_STATE_MASK(state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_OFFLINE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_TYPE_FCTL_ASYNC, NULL, NULL, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " fp_statec_cb() couldn't submit a job "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " to the thread: failing..");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Zero out this field so that we do not retain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fabric name as its no longer valid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&port->fp_fabric_name, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_state = state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_state = state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_offline_tid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timeout_id_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tid = port->fp_offline_tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_offline_tid = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_ONLINE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_TYPE_FCTL_ASYNC, NULL, NULL, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_statec_cb() couldn't submit a job "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "to the thread: failing..");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_RESET_REQUESTED:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_state = FC_STATE_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_FCA_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_RESET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_ULP_NOTIFY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_TYPE_FCTL_ASYNC, NULL, NULL, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_statec_cb() couldn't submit a job"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " to the thread: failing..");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* squeeze into some field in the job structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_listlen = FC_PORT_STATE_MASK(state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_TARGET_PORT_RESET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_notify(port, state, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_NAMESERVICE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register with the Name Server for RSCNs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_scr(fc_local_port_t *port, job_request_t *job, uchar_t scr_func,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t class;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_scr_req_t payload;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port->fp_ns_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_scr_req_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_scr_resp_t), sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, s_id, 0xFFFFFD, fp_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_SCR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.scr_rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.scr_func = scr_func;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There are basically two methods to determine the total number of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices out in the NS database; Reading the details of the two
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * methods described below, it shouldn't be hard to identify which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the two methods is better.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Method 1.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Iteratively issue GANs until all ports identifiers are walked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Method 2.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Issue GID_PT (get port Identifiers) with Maximum residual
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * field in the request CT HEADER set to accommodate only the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CT HEADER in the response frame. And if FC-GS2 has been
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * carefully read, the NS here has a chance to FS_ACC the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request and indicate the residual size in the FS_ACC.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Method 2 is wonderful, although it's not mandatory for the NS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to update the Maximum/Residual Field as can be seen in 4.3.1.6
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (note with particular care the use of the auxiliary verb 'may')
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_get_devcount(fc_local_port_t *port, job_request_t *job, int create,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!create && (port->fp_options & FP_NS_SMART_COUNT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pt_t), 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FCTL_NS_GET_DEV_COUNT | FCTL_NS_NO_DATA_BUF), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pt_t *)(ns_cmd->ns_cmd_buf))->port_type.port_type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte = FC_NS_PORT_NX; /* All port types */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pt_t *)(ns_cmd->ns_cmd_buf))->port_type.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ns_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_flags = FCTL_NS_GET_DEV_COUNT | FCTL_NS_NO_DATA_BUF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (create) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_flags |= FCTL_NS_CREATE_DEVICE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gan_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gan_t), sizeof (int), ns_flags, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = FCTL_GAN_START_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GA_NXT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_max = 0xFFFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gan_t *)(ns_cmd->ns_cmd_buf))->pid.port_id = src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gan_t *)(ns_cmd->ns_cmd_buf))->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = job->job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags &= ~JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags = flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!create && (port->fp_options & FP_NS_SMART_COUNT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t max_resid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Revert to scanning the NS if NS_GID_PT isn't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * helping us figure out total number of devices.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_hdr.ct_cmdrsp != FS_ACC_IU) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options &= ~FP_NS_SMART_COUNT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fp_ns_get_devcount(port, job, create, sleep));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_resid = ns_cmd->ns_resp_hdr.ct_aiusize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (max_resid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since port identifier is 4 bytes and max_resid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is also in WORDS, max_resid simply indicates
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the total number of port identifiers not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * transferred
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices += max_resid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices = *((int *)ns_cmd->ns_data_buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * One heck of a function to serve userland.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fciocmd(fc_local_port_t *port, intptr_t data, int mode, fcio_t *fcio)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int jcode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t open_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio_t *kfcio;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte boolean_t use32 = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _MULTI_DATAMODEL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ddi_model_convert_from(mode & FMODELS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_ILP32:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte use32 = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_NONE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_SOFT_IN_UNSOL_CB)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_STATEC_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EAGAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte open_flag = port->fp_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_check_perms(open_flag, fcio->fcio_cmd) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EACCES;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an exclusive open was demanded during open, don't let
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * either innocuous or devil threads to share the file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * descriptor and fire down exclusive access commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_flag & FP_EXCL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_flag & FP_EXCL_BUSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_flag |= FP_EXCL_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
1770502e3d1e6d2a0c07529d1699cf722a70501bYu Renia Miao fcio->fcio_errno = FC_SUCCESS;
1770502e3d1e6d2a0c07529d1699cf722a70501bYu Renia Miao
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (fcio->fcio_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_HOST_PARAMS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_dev_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_dev32_t *val32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int lilp_device_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_lilpmap_t *lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t *alpa_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (*val32) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (*val) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_did = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_hard_addr = port->fp_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_pwwn = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_nwwn = port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_state = port->fp_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map = &port->fp_lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alpa_list = &lilp_map->lilp_alpalist[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_device_count = lilp_map->lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < lilp_device_count; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = alpa_list[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d_id == port->fp_port_id.port_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_did.priv_lilp_posit = (uint8_t)(index & 0xff);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_fc4_types, val->dev_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_fc4_types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32 = kmem_zalloc(sizeof (*val32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_did = val->dev_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_hard_addr = val->dev_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_pwwn = val->dev_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_nwwn = val->dev_nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_state = val->dev_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->dev_did.priv_lilp_posit =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->dev_did.priv_lilp_posit;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->dev_type, val32->dev_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_fc4_types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val32, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val32, sizeof (*val32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* need to free "val" here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_OTHER_ADAPTER_PORTS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *tmpPath;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_local_port_t *tmpPort;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < MAXPATHLEN ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_ilen != sizeof (uint32_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &index, sizeof (index), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPort = fctl_get_adapter_port_by_index(port, index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpPort == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "User supplied index out of range");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPath = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_pathname(tmpPort->fp_port_dip, tmpPath);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)tmpPath, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MAXPATHLEN, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(tmpPath, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_NPIV_GET_ADAPTER_ATTRIBUTES:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_ADAPTER_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_adapter_attributes_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_adapter_attributes32_t *val32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val32) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->version = FC_HBA_ADAPTER_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.manufacturer,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->Manufacturer,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->Manufacturer));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.serial_number,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->SerialNumber,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->SerialNumber));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.model,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->Model,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->Model));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.model_description,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->ModelDescription,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->ModelDescription));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_sym_node_name, val->NodeSymbolicName,
c45ce861db6885aef2a2f6d0f4658176a6247716bing hu - Sun Microsystems - Beijing China port->fp_sym_node_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.hardware_version,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->HardwareVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->HardwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.option_rom_version,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->OptionROMVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->OptionROMVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.firmware_version,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->FirmwareVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->FirmwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->VendorSpecificID =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_hba_port_attrs.vendor_specific_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.node_ww_name.raw_wwn,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed &val->NodeWWN.raw_wwn,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.driver_name,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->DriverName,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->DriverName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_hba_port_attrs.driver_version,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->DriverVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->DriverVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_cmd == FCIO_GET_ADAPTER_ATTRIBUTES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberOfPorts = fctl_count_fru_ports(port, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberOfPorts = fctl_count_fru_ports(port, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32 = kmem_zalloc(sizeof (*val32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->version = val->version;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->Manufacturer, val32->Manufacturer,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->Manufacturer));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->SerialNumber, val32->SerialNumber,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->SerialNumber));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->Model, val32->Model,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->Model));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->ModelDescription, val32->ModelDescription,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->ModelDescription));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->NodeSymbolicName, val32->NodeSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeSymbolicName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->HardwareVersion, val32->HardwareVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->HardwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->OptionROMVersion, val32->OptionROMVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->OptionROMVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->FirmwareVersion, val32->FirmwareVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->FirmwareVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->VendorSpecificID = val->VendorSpecificID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->NodeWWN.raw_wwn, &val32->NodeWWN.raw_wwn,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->DriverName, val32->DriverName,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->DriverName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->DriverVersion, val32->DriverVersion,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->DriverVersion));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->NumberOfPorts = val->NumberOfPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val32, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val32, sizeof (*val32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_NPIV_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_npiv_attributes_t *attrs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attrs = kmem_zalloc(sizeof (*attrs), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.node_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &attrs->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (attrs->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &attrs->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (attrs->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)attrs, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(attrs, sizeof (*attrs));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DELETE_NPIV_PORT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww_pname[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t vwwn[1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "Delete NPIV Port");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &vwwn, sizeof (la_wwn_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&vwwn[0], ww_pname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Delete NPIV Port %s", ww_pname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = fc_delete_npiv_port(port, &vwwn[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpport == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Delete NPIV Port : no found");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *nextport = tmpport->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *prevport = tmpport->fp_port_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portlen, portindex, ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portlen = sizeof (portindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_prop_op(DDI_DEV_T_ANY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport->fp_port_dip, PROP_LEN_AND_VAL_BUF,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "port",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&portindex, &portlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ndi_devi_offline(tmpport->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NDI_DEVI_REMOVE) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Delete NPIV Port failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport->fp_npiv_state = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nextport->fp_port_prev = prevport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prevport->fp_port_next = nextport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port == port->fp_port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_next =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_npiv_portnum--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Delete NPIV Port %d", portindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_npiv_portindex[portindex-1] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_CREATE_NPIV_PORT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww_nname[17], ww_pname[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_npiv_create_entry_t entrybuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t vportindex = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int npiv_ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *portname, *fcaname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_pathname(port->fp_port_dip, portname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcaname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_pathname(port->fp_fca_dip, fcaname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Create NPIV port %s %s %s", portname, fcaname,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_driver_name(port->fp_fca_dip));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(portname, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fcaname, MAXPATHLEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &entrybuf, sizeof (la_npiv_create_entry_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&entrybuf.VNodeWWN, ww_nname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&entrybuf.VPortWWN, ww_pname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vportindex = entrybuf.vindex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Create NPIV Port %s %s %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww_nname, ww_pname, vportindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_get_npiv_port(port, &entrybuf.VPortWWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npiv_ret = fctl_fca_create_npivport(port->fp_fca_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_dip, ww_nname, ww_pname, &vportindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (npiv_ret == NDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_npiv_portnum++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&vportindex,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Create NPIV Port %d %d", npiv_ret, vportindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_NPIV_PORT_LIST: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_npiv_port_list_t *list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fcio->fcio_xfer != FCIO_XFER_READ) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_olen == 0) || (fcio->fcio_obuf == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->version = FC_HBA_LIST_VERSION;
c465437abaf8cc10b6cafec2fc1576bc770537baallan
c465437abaf8cc10b6cafec2fc1576bc770537baallan count = (fcio->fcio_olen -
c465437abaf8cc10b6cafec2fc1576bc770537baallan (int)sizeof (fc_hba_npiv_port_list_t))/MAXPATHLEN + 1;
c465437abaf8cc10b6cafec2fc1576bc770537baallan if (port->fp_npiv_portnum > count) {
c465437abaf8cc10b6cafec2fc1576bc770537baallan list->numAdapters = port->fp_npiv_portnum;
c465437abaf8cc10b6cafec2fc1576bc770537baallan } else {
c465437abaf8cc10b6cafec2fc1576bc770537baallan /* build npiv port list */
c465437abaf8cc10b6cafec2fc1576bc770537baallan count = fc_ulp_get_npiv_port_list(port,
c465437abaf8cc10b6cafec2fc1576bc770537baallan (char *)list->hbaPaths);
c465437abaf8cc10b6cafec2fc1576bc770537baallan if (count < 0) {
c465437abaf8cc10b6cafec2fc1576bc770537baallan rval = ENXIO;
c465437abaf8cc10b6cafec2fc1576bc770537baallan FP_TRACE(FP_NHEAD1(1, 0),
c465437abaf8cc10b6cafec2fc1576bc770537baallan "Build NPIV Port List error");
c465437abaf8cc10b6cafec2fc1576bc770537baallan kmem_free(list, fcio->fcio_olen);
c465437abaf8cc10b6cafec2fc1576bc770537baallan break;
c465437abaf8cc10b6cafec2fc1576bc770537baallan }
c465437abaf8cc10b6cafec2fc1576bc770537baallan list->numAdapters = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)list, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Copy NPIV Port data error");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "Copy NPIV Port List error");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(list, fcio->fcio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_ADAPTER_PORT_NPIV_ATTRIBUTES: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_hba_port_npiv_attributes_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->version = FC_HBA_PORT_NPIV_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->npivflag = port->fp_npiv_flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->lastChange = port->fp_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.node_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberOfNPIVPorts = fc_ulp_get_npiv_port_num(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_npiv_type != FC_NPIV_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->MaxNumberOfNPIVPorts =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_num_npivports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->MaxNumberOfNPIVPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_ADAPTER_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes32_t *val32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val32) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->lastChange = port->fp_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->fp_minor = port->fp_instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_service_params.node_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_fabric_name, &val->FabricName.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->FabricName.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortFcId = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (FC_PORT_STATE_MASK(port->fp_state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_OFFLINE:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortState = FC_HBA_PORTSTATE_OFFLINE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_NAMESERVICE:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortState = FC_HBA_PORTSTATE_ONLINE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortState = FC_HBA_PORTSTATE_UNKNOWN;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Translate from LV to FC-HBA port type codes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_port_type.port_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_N:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_NPORT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed case FC_NS_PORT_NL:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed /* Actually means loop for us */
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_LPORT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_F:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_FPORT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_FL:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_FLPORT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_E:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_EPORT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortType = FC_HBA_PORTTYPE_OTHER;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fp has decided that the topology is public loop,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will indicate that using the appropriate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC HBA API constant.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortType = FC_HBA_PORTTYPE_NLPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortType = FC_HBA_PORTTYPE_PTP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_UNKNOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This should cover the case where nothing is connected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the port. Crystal+ is p'bly an exception here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For Crystal+, port 0 will come up as private loop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (i.e fp_bind_state will be FC_STATE_LOOP) even when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nothing is connected to it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Current plan is to let userland handle this.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (port->fp_bind_state == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortType = FC_HBA_PORTTYPE_UNKNOWN;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do Nothing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unused:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * val->PortType = FC_HBA_PORTTYPE_GPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_hba_port_attrs.supported_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedFc4Types[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_fc4_types, val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortActiveFc4Types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_sym_port_name, val->PortSymbolicName,
c45ce861db6885aef2a2f6d0f4658176a6247716bing hu - Sun Microsystems - Beijing China port->fp_sym_port_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedSpeed =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_hba_port_attrs.supported_speed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (FC_PORT_SPEED_MASK(port->fp_state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_1GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_1GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_2GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_2GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_4GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_4GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_8GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_8GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_10GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_10GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_16GBIT_SPEED:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_16GBIT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed val->PortSpeed = FC_HBA_PORTSPEED_UNKNOWN;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortMaxFrameSize = port->fp_hba_port_attrs.max_frame_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts = port->fp_dev_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32 = kmem_zalloc(sizeof (*val32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->version = val->version;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->lastChange = val->lastChange;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->fp_minor = val->fp_minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->PortWWN.raw_wwn, &val32->PortWWN.raw_wwn,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->NodeWWN.raw_wwn, &val32->NodeWWN.raw_wwn,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortFcId = val->PortFcId;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortState = val->PortState;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortType = val->PortType;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedClassofService =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortActiveFc4Types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortSymbolicName, val32->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortSymbolicName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->FabricName, &val32->FabricName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->FabricName.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedSpeed = val->PortSupportedSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSpeed = val->PortSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortMaxFrameSize = val->PortMaxFrameSize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->NumberofDiscoveredPorts =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val32, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val32, sizeof (*val32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_DISCOVERED_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes32_t *val32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val32) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &index, sizeof (index), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (index >= port->fp_dev_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "User supplied index out of range");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_OUTOFBOUNDS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_lookup_pd_by_index(port, index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->lastChange = port->fp_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->fp_minor = port->fp_instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&tmp_pd->pd_port_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&tmp_pd->pd_remote_nodep->fd_node_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortFcId = tmp_pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(tmp_pd->pd_spn, val->PortSymbolicName,
c45ce861db6885aef2a2f6d0f4658176a6247716bing hu - Sun Microsystems - Beijing China tmp_pd->pd_spn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService = tmp_pd->pd_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will assume the sizeof these pd_fc4types and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * portActiveFc4Types will remain the same. we could
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add in a check for it, but we decided it was unneeded
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)tmp_pd->pd_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (tmp_pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortState =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_map_remote_port_state(tmp_pd->pd_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortType = FC_HBA_PORTTYPE_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedFc4Types[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortMaxFrameSize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32 = kmem_zalloc(sizeof (*val32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->version = val->version;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->lastChange = val->lastChange;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->fp_minor = val->fp_minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val32->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val32->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortFcId = val->PortFcId;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortSymbolicName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedClassofService =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (tmp_pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortType = val->PortType;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortState = val->PortState;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedFc4Types[0] =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedFc4Types[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedSpeed =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSpeed = val->PortSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortMaxFrameSize =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortMaxFrameSize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->NumberofDiscoveredPorts =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val32,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (fp_fcio_copyout(fcio,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed data, mode)) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rval = EFAULT;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val32, sizeof (*val32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_PORT_ATTRIBUTES: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes_t *val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_hba_port_attributes32_t *val32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val32) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < sizeof (*val) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &wwn, sizeof (wwn), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = kmem_zalloc(sizeof (*val), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = fctl_lookup_pd_by_wwn(port, wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->lastChange = port->fp_last_change;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->fp_minor = port->fp_instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&tmp_pd->pd_port_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&tmp_pd->pd_remote_nodep->fd_node_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortFcId = tmp_pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(tmp_pd->pd_spn, val->PortSymbolicName,
c45ce861db6885aef2a2f6d0f4658176a6247716bing hu - Sun Microsystems - Beijing China tmp_pd->pd_spn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService = tmp_pd->pd_cos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortType = FC_HBA_PORTTYPE_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortState =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_map_remote_port_state(tmp_pd->pd_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedFc4Types[0] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will assume the sizeof these pd_fc4types and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * portActiveFc4Types will remain the same. we could
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * add in a check for it, but we decided it was unneeded
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)tmp_pd->pd_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (tmp_pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSpeed = FC_HBA_PORTSPEED_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortMaxFrameSize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmp_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32 = kmem_zalloc(sizeof (*val32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->version = val->version;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->lastChange = val->lastChange;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->fp_minor = val->fp_minor;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val32->PortWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&val->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &val32->NodeWWN.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->NodeWWN.raw_wwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortFcId = val->PortFcId;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSymbolicName,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (val->PortSymbolicName));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedClassofService =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedClassofService;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortType = val->PortType;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortState = val->PortState;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedFc4Types[0] =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedFc4Types[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(val->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortActiveFc4Types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (tmp_pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSupportedSpeed =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->PortSupportedSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortSpeed = val->PortSpeed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->PortMaxFrameSize = val->PortMaxFrameSize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val32->NumberofDiscoveredPorts =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val->NumberofDiscoveredPorts;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val32,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val32, sizeof (*val32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)val,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(val, sizeof (*val));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_NUM_DEVS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (num_devices) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_NS_CMD, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In FC-GS-2 the Name Server doesn't send out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RSCNs for any Name Server Database updates
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When it is finally fixed there is no need
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to probe as below and should be removed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ns_get_devcount(port, job, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_UNKNOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&num_devices,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf, fcio->fcio_olen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_DEV_LIST: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int new_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int map_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_alen != sizeof (new_count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = fcio->fcio_olen / sizeof (fc_port_dev_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (num_devices < port->fp_total_devices) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_TOOMANY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_count = port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&new_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (new_count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_total_devices <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NO_MAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_count = port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&new_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (new_count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (port->fp_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PRIVATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fillout_loopmap(port, fcio,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PT_PT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fillout_p2pmap(port, fcio,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_PUBLIC_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_FABRIC: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map_size =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_port_dev_t) * port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gan_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gan_t), map_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FCTL_NS_FILL_NS_MAP | FCTL_NS_BUF_IS_USERLAND),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = FCTL_GAN_START_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GA_NXT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_max = map_size / sizeof (fc_port_dev_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_GETMAP, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&new_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (new_count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_count = ns_cmd->ns_gan_index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&new_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_abuf, sizeof (new_count),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)ns_cmd->ns_data_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf, sizeof (fc_port_dev_t) *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_NO_NS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TOP_UNKNOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NO_MAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&new_count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (new_count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_SYM_PNAME: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTSUP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_SYM_NNAME: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTSUP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_SET_SYM_PNAME: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTSUP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_SET_SYM_NNAME: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTSUP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_LOGI_PARAMS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *my_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t *params;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi32_t *params32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (la_els_logi32_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (la_els_logi_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &pwwn, sizeof (pwwn), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte my_pwwn = &port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&pwwn, my_pwwn) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params = kmem_zalloc(sizeof (*params), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *params = port->fp_service_params;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params = kmem_zalloc(sizeof (*params), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->ls_code.mbz = params->ls_code.ls_code = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->common_service = pd->pd_csp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->nport_ww_name = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->class_1 = pd->pd_clsp1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->class_2 = pd->pd_clsp2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->class_3 = pd->pd_clsp3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(params->reserved, sizeof (params->reserved));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(node->fd_vv, params->vendor_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (node->fd_vv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params->node_ww_name = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32 = kmem_zalloc(sizeof (*params32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->ls_code.mbz = params->ls_code.mbz;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->common_service = params->common_service;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->nport_ww_name = params->nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->class_1 = params->class_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->class_2 = params->class_2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->class_3 = params->class_3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(params32->reserved, sizeof (params32->reserved));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(params->vendor_version, params32->vendor_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (node->fd_vv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte params32->node_ww_name = params->node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)params32,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*params32), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(params32, sizeof (*params32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)params, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*params), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(params, sizeof (*params));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DEV_LOGOUT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DEV_LOGIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_cmd == FCIO_DEV_LOGIN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte jcode = JOB_FCIO_LOGIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte jcode = JOB_FCIO_LOGOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfcio = kmem_zalloc(sizeof (*kfcio), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fcio, kfcio, sizeof (*fcio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (kfcio->fcio_ilen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfcio->fcio_ibuf = kmem_zalloc(kfcio->fcio_ilen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)fcio->fcio_ibuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)kfcio->fcio_ibuf, kfcio->fcio_ilen,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(kfcio->fcio_ibuf, kfcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(kfcio, sizeof (*kfcio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(jcode, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = kfcio;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = kfcio->fcio_errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(kfcio->fcio_ibuf, kfcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(kfcio, sizeof (*kfcio));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_STATE: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t state;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen != sizeof (state) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &pwwn, sizeof (pwwn), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PLOGI_ONE, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_BUF_IS_USERLAND, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS || job->job_result !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)&state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf, sizeof (state),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DEV_REMOVE: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &pwwn, sizeof (pwwn), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_ref_count > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EBUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = kmem_zalloc(sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(changelist, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_type = PORT_DEVICE_USER_LOGOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist, 1, 1, KM_SLEEP, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_FCODE_REV: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed caddr_t fcode_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < FC_FCODE_REV_SIZE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcode_rev = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_FCODE_REV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = fcio->fcio_olen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = fcode_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)fcode_rev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check if buffer was not large enough to obtain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCODE version.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm.pm_data_len > fcio->fcio_olen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fcode_rev, fcio->fcio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_FW_REV: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed caddr_t fw_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < FC_FW_REV_SIZE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fw_rev = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_FW_REV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = fcio->fcio_olen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = fw_rev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)fw_rev,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fw_rev, fcio->fcio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_DUMP_SIZE: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t dump_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != sizeof (dump_size) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_DUMP_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = sizeof (dump_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = (caddr_t)&dump_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)&dump_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf, sizeof (dump_size),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DOWNLOAD_FW: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t firmware;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen <= 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte firmware = kmem_zalloc(fcio->fcio_ilen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, firmware,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_ilen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(firmware, fcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_WRITE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_DOWNLOAD_FW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = fcio->fcio_ilen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = firmware;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(firmware, fcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DOWNLOAD_FCODE: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t fcode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen <= 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_WRITE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcode = kmem_zalloc(fcio->fcio_ilen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, fcode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_ilen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fcode, fcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_WRITE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_DOWNLOAD_FCODE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = fcio->fcio_ilen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = fcode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fcode, fcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_FORCE_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_CORE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_DUMP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t dump;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t dump_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_DUMP_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = sizeof (dump_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = (caddr_t)&dump_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen != dump_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dump = kmem_zalloc(dump_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_GET_DUMP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_len = dump_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = dump;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)dump, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dump_size, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dump, dump_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_TOPOLOGY: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t user_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen != sizeof (user_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte user_topology = FC_TOP_UNKNOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte user_topology = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)&user_topology,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf, sizeof (user_topology),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_RESET_LINK: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Look at the output buffer field; if this field has zero
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bytes then attempt to reset the local link/loop. If the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fcio_ibuf field points to a WWN, see if it's an NL_Port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and if yes, determine the LFA and reset the remote LIP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by LINIT ELS.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_xfer != FCIO_XFER_WRITE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_ilen != sizeof (pwwn)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pwwn), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_IN_LINK_RESET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_LINK_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_LINK_RESET, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)&pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_LINK_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_RESET_HARD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_RESET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_RESET_HARD_CORE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_RESET_CORE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_DIAG: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (fc_fca_pm_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Validate user buffer from ioctl call. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((fcio->fcio_ilen > 0) && (fcio->fcio_ibuf == NULL)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fcio->fcio_ilen <= 0) && (fcio->fcio_ibuf != NULL)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fcio->fcio_alen > 0) && (fcio->fcio_abuf == NULL)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fcio->fcio_alen <= 0) && (fcio->fcio_abuf != NULL)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fcio->fcio_olen > 0) && (fcio->fcio_obuf == NULL)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fcio->fcio_olen <= 0) && (fcio->fcio_obuf != NULL))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pm.pm_cmd_len = fcio->fcio_ilen) > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_buf = kmem_zalloc(fcio->fcio_ilen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, pm.pm_cmd_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_ilen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_fcio_diag_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pm.pm_data_len = fcio->fcio_alen) > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_data_buf = kmem_zalloc(fcio->fcio_alen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_abuf, pm.pm_data_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_alen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_fcio_diag_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pm.pm_stat_len = fcio->fcio_olen) > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_stat_buf = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_code = FC_PORT_DIAG;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = fcio->fcio_cmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_INVALID_REQUEST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTTY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_fcio_diag_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pm_stat_len will contain the number of status bytes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an FCA driver requires to return the complete status
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the requested diag operation. If the user buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is not large enough to hold the entire status, We
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * copy only the portion of data the fits in the buffer and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return a ENOMEM to the user application.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm.pm_stat_len > fcio->fcio_olen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp:FCIO_DIAG:status buffer too small\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(pm.pm_stat_buf, fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_fcio_diag_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy only data pm_stat_len bytes of data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(pm.pm_stat_buf, fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_stat_len, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_fcio_diag_cleanup;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_fcio_diag_cleanup:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm.pm_cmd_buf != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pm.pm_cmd_buf, fcio->fcio_ilen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm.pm_data_buf != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pm.pm_data_buf, fcio->fcio_alen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm.pm_stat_buf != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pm.pm_stat_buf, fcio->fcio_olen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_GET_NODE_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* validate parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen < sizeof (fc_rnid_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_get_rnid(port, data, mode, fcio);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ioctl handling is over */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_SEND_NODE_ID: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* validate parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, &pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_send_rnid(port, data, mode, fcio, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ioctl handling is over */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_SET_NODE_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (fc_rnid_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_xfer != FCIO_XFER_WRITE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_set_rnid(port, data, mode, fcio);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_LINK_STATUS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t rls_req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_rls_acc_t *rls_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t dest, src_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t pd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* validate parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (fc_portid_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_olen != sizeof (fc_rls_acc_t) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_xfer != FCIO_XFER_RW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fcio->fcio_cmd_flags != FCIO_CFLAGS_RLS_DEST_FPORT) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fcio->fcio_cmd_flags != FCIO_CFLAGS_RLS_DEST_NPORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)fcio->fcio_ibuf, (void *)&rls_req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_portid_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Determine the destination of the RLS frame */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_cmd_flags == FCIO_CFLAGS_RLS_DEST_FPORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest = FS_FABRIC_F_PORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest = rls_req.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If dest is zero OR same as FCA ID, then use port_manage() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dest == 0 || dest == src_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for link error status block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(rls_acc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Prepare the port management structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_cmd_code = FC_PORT_RLS;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_len = sizeof (*rls_acc);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_buf = (caddr_t)rls_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get the adapter's link error status block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* xfer link status block to userland */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)rls_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*rls_acc), mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rls_acc, sizeof (*rls_acc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ioctl handling is over */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send RLS to the destination port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Having RLS frame destination is as FPORT is not yet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * supported and will be implemented in future, if needed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Following call to get "pd" will fail if dest is FPORT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_did(port, dest);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADOBJECT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_LOGINREQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_login_count >= 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate job structure and set job_code as DUMMY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * because we will not go through the job thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Instead fp_sendcmd() is called directly here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_DUMMY, JOB_TYPE_FP_ASYNC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rls_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_rls_acc_t), KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for link error status block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_rls_init(cmd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)rls_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_flags = pd->pd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * link error status block is now available.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy it to userland
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_private == (void *)rls_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)rls_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*rls_acc), mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags == PD_ELS_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = pd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rls_acc, sizeof (*rls_acc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FCIO_NS: {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_ns_cmd_t *ns_req;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_ns_cmd32_t *ns_req32;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (use32 == B_TRUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (*ns_req32)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req = kmem_zalloc(sizeof (*ns_req), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req32 = kmem_zalloc(sizeof (*ns_req32), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, ns_req32,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*ns_req32), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req32, sizeof (*ns_req32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_flags = ns_req32->ns_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_cmd = ns_req32->ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_req_len = ns_req32->ns_req_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_req_payload = ns_req32->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_len = ns_req32->ns_resp_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_payload = ns_req32->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_fctl_private = ns_req32->ns_fctl_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_hdr = ns_req32->ns_resp_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req32, sizeof (*ns_req32));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_ilen != sizeof (*ns_req)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req = kmem_zalloc(sizeof (*ns_req), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, ns_req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_ns_cmd_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_req->ns_req_len <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_NS_CMD, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(ns_req->ns_req_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_len, ns_req->ns_resp_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_FILL_NS_MAP, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = ns_req->ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_code == NS_GA_NXT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_max = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = FCTL_GAN_START_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(ns_req->ns_req_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_buf, ns_req->ns_req_len, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_req->ns_resp_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(ns_cmd->ns_data_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_len, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_resp_hdr = ns_cmd->ns_resp_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_req, sizeof (*ns_req));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTTY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If set, reset the EXCL busy bit to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * receive other exclusive access commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_flag & FP_EXCL_BUSY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_flag &= ~FP_EXCL_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function assumes that the response length
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is same regardless of data model (LP32 or LP64)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which is true for all the ioctls currently
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * supported.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_copyout(void *from, void *to, size_t len, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ddi_copyout(from, to, len, mode));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function does the set rnid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_set_rnid(fc_local_port_t *port, intptr_t data, int mode, fcio_t *fcio)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_rnid_t *rnid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for node id block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnid = kmem_zalloc(sizeof (fc_rnid_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(fcio->fcio_ibuf, rnid, sizeof (fc_rnid_t), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_set_rnid: failed = %d", EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnid, sizeof (fc_rnid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Prepare the port management structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_WRITE;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_cmd_code = FC_PORT_SET_NODE_ID;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_len = sizeof (*rnid);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_buf = (caddr_t)rnid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get the adapter's node data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_port_manage(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy to the port structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(rnid, &port->fp_rnid_params,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (port->fp_rnid_params));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnid, sizeof (fc_rnid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_set_rnid: failed = %d", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function does the local pwwn get rnid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_get_rnid(fc_local_port_t *port, intptr_t data, int mode, fcio_t *fcio)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_rnid_t *rnid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_pm_t pm;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for rnid data block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnid = kmem_zalloc(sizeof (fc_rnid_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_rnid_init == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port->fp_rnid_params, rnid, sizeof (fc_rnid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* xfer node info to userland */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)rnid, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*rnid), mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnid, sizeof (fc_rnid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_get_rnid: failed = %d",
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Prepare the port management structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero((caddr_t)&pm, sizeof (pm));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_cmd_code = FC_PORT_GET_NODE_ID;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_len = sizeof (fc_rnid_t);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed pm.pm_data_buf = (caddr_t)rnid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get the adapter's node data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->fp_fca_tran->fca_port_manage(
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_fca_handle,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed &pm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* initialize in the port_info */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_rnid_init = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(rnid, &port->fp_rnid_params, sizeof (*rnid));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* xfer node info to userland */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)rnid,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (void *)fcio->fcio_obuf,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed sizeof (*rnid), mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnid, sizeof (fc_rnid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_get_rnid: failed = %d", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_send_rnid(fc_local_port_t *port, intptr_t data, int mode, fcio_t *fcio,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_rnid_acc_t *rnid_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We can safely assume that the destination port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is logged in. Either the user land will explicitly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * login before issuing RNID ioctl or the device would
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have been configured, meaning already logged in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_send_rnid: failed = %d", ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate job structure and set job_code as DUMMY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * because we will not go thorugh the job thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Instead fp_sendcmd() is called directly here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_DUMMY, JOB_TYPE_FP_ASYNC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rnid_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_rnid_acc_t), KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_send_rnid: failed = %d", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allocate memory for node id accept block */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnid_acc = kmem_zalloc(sizeof (la_els_rnid_acc_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_rnid_init(cmd, fcio->fcio_cmd_flags, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)rnid_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rnid_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node id block is now available.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy it to userland
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job->job_private == (void *)rnid_acc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get the response length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnid_cnt = sizeof (ls_code_t) + sizeof (fc_rnid_hdr_t) +
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rnid_acc->hdr.cmn_len +
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rnid_acc->hdr.specific_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcio->fcio_olen < rnid_cnt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ddi_copyout((void *)rnid_acc,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (void *)fcio->fcio_obuf,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed rnid_cnt, mode) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnid_acc, sizeof (la_els_rnid_acc_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_fcio_copyout(fcio, data, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_send_rnid: failed = %d", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy out to userland
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fcio_copyout(fcio_t *fcio, intptr_t data, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _MULTI_DATAMODEL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ddi_model_convert_from(mode & FMODELS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_ILP32: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fcio32 fcio32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_xfer = fcio->fcio_xfer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_cmd = fcio->fcio_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_flags = fcio->fcio_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_cmd_flags = fcio->fcio_cmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_ilen = fcio->fcio_ilen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_ibuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr32_t)(uintptr_t)fcio->fcio_ibuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_olen = fcio->fcio_olen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_obuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr32_t)(uintptr_t)fcio->fcio_obuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_alen = fcio->fcio_alen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_abuf =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (caddr32_t)(uintptr_t)fcio->fcio_abuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio32.fcio_errno = fcio->fcio_errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_copyout((void *)&fcio32, (void *)data,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct fcio32), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_MODEL_NONE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_copyout((void *)fcio, (void *)data,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fcio_t), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_copyout((void *)fcio, (void *)data, sizeof (fcio_t), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_p2p_online(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_topology == FC_TOP_PT_PT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port, &changelist, &listlen, 1, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_statec_cb(port, FC_STATE_ONLINE, changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen, listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(changelist == NULL && listlen == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_p2pmap(fc_local_port_t *port, fcio_t *fcio, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_port_dev_t *devlist;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed struct pwwn_hash *head;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = fcio->fcio_olen / sizeof (fc_port_dev_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist = kmem_zalloc(sizeof (fc_port_dev_t) * num_devices, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_hard_addr = pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_did = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_did.priv_lilp_posit =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t)(index & 0xff);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)pd->pd_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)devlist[count].dev_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&pd->pd_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&devlist[count].dev_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&node->fd_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&devlist[count].dev_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count >= num_devices) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto found;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefound:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&count, (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (fp_copyout((void *)devlist, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_port_dev_t) * num_devices, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(devlist, sizeof (fc_port_dev_t) * num_devices);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle Fabric ONLINE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fabric_online(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int dbg_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count = 0;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *npd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(FC_IS_TOP_SWITCH(port->fp_topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t), sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if orphans are showing up now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_orphan_count) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *norp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (orp = port->fp_orphan_list; orp; orp = norp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte norp = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp->orp_nscan++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pwwn = orp->orp_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf)->pid.port_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf)->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BE_32(*((uint32_t *)ns_cmd->ns_data_buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fp_create_remote_port_by_ns(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&orp->orp_pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_WARN, FP_LOG_ONLY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, NULL, "N_x Port with D_ID=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " PWWN=%s reappeared in fabric",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->orp_next = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(orp ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(orp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_MARK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orp->orp_nscan == FC_ORPHAN_SCAN_LIMIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&orp->orp_pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Port WWN %s removed from orphan"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " list after %d scans", ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp->orp_nscan);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->orp_next = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(orp ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(orp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk the Port WWN hash table, reestablish LOGIN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if a LOGIN is already performed on a particular
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device; Any failure to LOGIN should mark the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port device OLD.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((pd = npd) != NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't count in the port devices that are new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unless the total number of devices visible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * through this port is less than FP_MAX_DEVICES
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_dev_count >= FP_MAX_DEVICES ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_options & FP_TARGET_MODE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_NEW ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags == PD_ELS_MARK ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient != PD_PLOGI_INITIATOR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags == PD_ELS_MARK ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient != PD_PLOGI_INITIATOR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Consult with the name server about D_ID changes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf)->pid.port_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)ns_cmd->ns_data_buf)->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_MARK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_DELETE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_fabric_online: PD "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "disappeared; d_id=%x, PWWN=%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " disappeared from fabric", d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = BE_32(*((uint32_t *)ns_cmd->ns_data_buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d_id != pd->pd_port_id.port_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "D_ID of a device with PWWN %s changed."
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " New D_ID = %x, OLD D_ID = %x", ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, pd->pd_port_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id = BE_32(d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_IN_FCA_RESET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_FCA_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(FLA_RR_TOV * 1000 * 1000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((pd = npd) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags != PD_ELS_MARK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If it is already marked deletion, nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * else to do.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_DELETE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If it is freshly discovered out of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the orphan list, nothing else to do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_NEW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Explicitly mark all devices OLD; successful
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI should reset this to either NO_CHANGE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or CHANGED.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type != PORT_DEVICE_CHANGED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, KM_SLEEP, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(dbg_count == count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_statec_busy > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_statec_busy > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_CANCEL_ULP_NOTIFICATION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((job->job_flags & JOB_CANCEL_ULP_NOTIFICATION) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port, &changelist, &listlen, 1, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_statec_cb(port, FC_STATE_ONLINE, changelist,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen, listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(changelist == NULL && listlen == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_statec_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_STATEC_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill out device list for userland ioctl in private loop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_loopmap(fc_local_port_t *port, fcio_t *fcio, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_port_dev_t *devlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int lilp_device_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_lilpmap_t *lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t *alpa_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices = fcio->fcio_olen / sizeof (fc_port_dev_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_total_devices > port->fp_dev_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_devices >= port->fp_total_devices) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PORT_GETMAP, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_get_loopmap(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist = kmem_zalloc(sizeof (*devlist) * num_devices, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Applications are accustomed to getting the device list in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LILP map order. The HBA firmware usually returns the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * map in the LILP map order and diagnostic applications would
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * prefer to receive in the device list in that order too
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_map = &port->fp_lilp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alpa_list = &lilp_map->lilp_alpalist[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the length field corresponds to the offset in the LILP frame
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which begins with 1. The thing to note here is that the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lilp_device_count is 1 more than fp->fp_total_devices since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the host adapter's alpa also shows up in the lilp map. We
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't however return details of the host adapter since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_get_remote_port_by_did fails for the host adapter's ALPA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and applications are required to issue the FCIO_GET_HOST_PARAMS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ioctl to obtain details about the host adapter port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lilp_device_count = lilp_map->lilp_length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = index = 0; index < lilp_device_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count < num_devices; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = alpa_list[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_hard_addr = pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_did = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devlist[count].dev_did.priv_lilp_posit =
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (uint8_t)(index & 0xff);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)pd->pd_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)devlist[count].dev_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&pd->pd_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&devlist[count].dev_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)&node->fd_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&devlist[count].dev_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)&count, (void *)fcio->fcio_abuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (count), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_copyout((void *)devlist, (void *)fcio->fcio_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_port_dev_t) * num_devices, mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(devlist, sizeof (*devlist) * num_devices);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Completion function for responses to unsolicited commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_unsol_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_WARN, FP_LOG_ONLY, 0, pkt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "couldn't post response to unsolicited request;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ox_id=%x rx_id=%x", pkt->pkt_cmd_fhdr.ox_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_resp_fhdr.rx_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == port->fp_els_resp_pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * solicited LINIT ELS completion function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_linit_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_linit_resp_t acc;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = ((fp_cmd_t *)pkt->pkt_ulp_private)->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed cmd = (fp_cmd_t *)pkt->pkt_ulp_private;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed cmd->cmd_port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&cmd->cmd_port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = cmd->cmd_job;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (acc.status != FC_LINIT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decode the unsolicited request; For FC-4 Device and Link data frames
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * notify the registered ULP of this FC-4 type right here. For Unsolicited
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ELS requests, submit a request to the job_handler thread to work on it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The intent is to act quickly on the FC-4 unsolicited link and data frames
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and save much of the interrupt time processing of unsolicited ELS requests
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and hand it off to the job_handler thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_unsol_cb(opaque_t port_handle, fc_unsol_buf_t *buf, uint32_t type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t ls_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t rscn_count = FC_INVALID_RSCN_COUNT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "fp_unsol_cb: s_id=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " d_id=%x, type=%x, r_ctl=%x, f_ctl=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " seq_id=%x, df_ctl=%x, seq_cnt=%x, ox_id=%x, rx_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ro=%x, buffer[0]:%x", buf->ub_frame.s_id, buf->ub_frame.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.type, buf->ub_frame.r_ctl, buf->ub_frame.f_ctl,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.seq_id, buf->ub_frame.df_ctl, buf->ub_frame.seq_cnt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.ox_id, buf->ub_frame.rx_id, buf->ub_frame.ro,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_buffer[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (type & 0x80000000) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Huh ? Nothing much can be done without
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a valid buffer. So just exit.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the unsolicited interrupts arrive while it isn't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * safe to handle unsolicited callbacks; Drop them, yes,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * drop them on the floor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_active_ubs++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_SOFT_SUSPEND | FP_SOFT_POWER_DOWN)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PORT_STATE_MASK(port->fp_state) == FC_STATE_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_unsol_cb: port state is "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "not ONLINE. s_id=%x, d_id=%x, type=%x, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "seq_id=%x, ox_id=%x, rx_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ro=%x", buf->ub_frame.s_id, buf->ub_frame.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.type, buf->ub_frame.seq_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.ox_id, buf->ub_frame.rx_id, buf->ub_frame.ro);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte r_ctl = buf->ub_frame.r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = buf->ub_frame.s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_active_ubs == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (r_ctl == R_CTL_ELS_REQ && buf->ub_buffer[0] == LA_ELS_LOGO &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "LOGO for LOGGED IN D_ID %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_unsol_cb() bailing out LOGO for D_ID %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_els_resp_pkt_busy == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (r_ctl == R_CTL_ELS_REQ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code = buf->ub_buffer[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ls_code) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_PLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_FLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_i_handle_unsol_els(port, buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_RSCN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(port)->fp_rscn_count ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++(port)->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_count = port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((r_ctl == R_CTL_ELS_REQ) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (buf->ub_buffer[0] == LA_ELS_RSCN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_count = port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (r_ctl & R_CTL_ROUTING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_DEVICE_DATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the unsolicited buffer is a CT IU,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have the job_handler thread work on it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_frame.type == FC_TYPE_FC_SERVICES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_FC4_SVC: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sendup = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a LOGIN isn't performed before this request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * shut the door on this port with a reply that a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LOGIN is required. We make an exception however
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for IP broadcast packets and pass them through
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the IP ULP(s) to handle broadcast requests.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is not a problem for private loop devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but for fabric topologies we don't log into the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remote ports during port initialization and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the ULPs need to log into requesting ports on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * demand.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sendup++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((pd == NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (buf->ub_frame.type == FC_TYPE_IS8802_SNAP) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (buf->ub_frame.d_id == 0xffffff ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.d_id == 0x00)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* brodacst IP frame - so sendup via job thread */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send all FC4 services via job thread too
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((r_ctl & R_CTL_ROUTING) == R_CTL_FC4_SVC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sendup || !FC_IS_REAL_DEVICE(s_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_unsol_cb(port, buf, buf->ub_frame.type);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_NOSLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_LOGIN_REQUIRED, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Submit a Request to the job_handler thread to work
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the unsolicited request. The potential side effect
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of this is that the unsolicited buffer takes a little
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * longer to get released but we save interrupt time in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the bargain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cb_arg = (rscn_count == FC_INVALID_RSCN_COUNT) ? NULL : rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * One way that the rscn_count will get used is described below :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1. fp_unsol_cb() gets an RSCN and updates fp_rscn_count.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2. Before mutex is released, a copy of it is stored in rscn_count.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 3. The count is passed to job thread as JOB_UNSOL_REQUEST (below)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by overloading the job_cb_arg to pass the rscn_count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 4. When one of the routines processing the RSCN picks it up (ex:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_validate_rscn_page()), it passes this count in the map
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structure (as part of the map_rscn_info structure member) to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 5. When ULPs make calls back to the transport (example interfaces for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this are fc_ulp_transport(), fc_ulp_login(), fc_issue_els()), they
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can now pass back this count as part of the fc_packet's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pkt_ulp_rscn_count member. fcp does this currently.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 6. When transport gets a call to transport a command on the wire, it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will check to see if there is a valid pkt_ulp_rsvd1 field in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_packet. If there is, it will match that info with the current
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rscn_count on that instance of the port. If they don't match up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then there was a newer RSCN. The ULP gets back an error code which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * informs it about it - FC_DEVICE_BUSY_NEW_RSCN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 7. At this point the ULP is free to make up its own mind as to how to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle this. Currently, fcp will reset its retry counters and keep
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * retrying the operation it was doing in anticipation of getting a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * new state change call back for the new RSCN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_UNSOL_REQUEST, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)(uintptr_t)cb_arg, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL, "fp_unsol_cb() "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "couldn't submit a job to the thread, failing..");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle unsolicited requests
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_buf(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t ls_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_spec_t *ub_spec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte r_ctl = buf->ub_frame.r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = buf->ub_frame.s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (r_ctl & R_CTL_ROUTING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_EXTENDED_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (r_ctl != R_CTL_ELS_REQ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code = buf->ub_buffer[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ls_code) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_LOGO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_ADISC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_PRLO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FC_IS_REAL_DEVICE(s_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd = fp_alloc_pkt(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_rjt_t), 0, KM_SLEEP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Can this actually fail when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given KM_SLEEP? (Could be used
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this way in a number of places.)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ls_code == LA_ELS_LOGO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_logo(port, buf, pd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ls_code == LA_ELS_ADISC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_adisc(port, buf, pd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_prlo(port, buf, pd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_PLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_plogi(port, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_FLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_flogi(port, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_RSCN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_handle_unsol_rscn(port, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec = kmem_zalloc(sizeof (*ub_spec), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec->port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec->buf = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) taskq_dispatch(port->fp_taskq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ulp_unsol_cb, ub_spec, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_BASIC_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The unsolicited basic link services could be ABTS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and RMC (Or even a NOP). Just BA_RJT them until
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * such time there arises a need to handle them more
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * carefully.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_ba_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ba_rjt_init(port, cmd, buf, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_DEVICE_DATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_frame.type == FC_TYPE_FC_SERVICES) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mostly this is of type FC_TYPE_FC_SERVICES.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * As we don't like any Unsolicited FC services
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * requests, we would do well to RJT them as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * well.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_FC4_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec = kmem_zalloc(sizeof (*ub_spec), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec->port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec->buf = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) taskq_dispatch(port->fp_taskq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ulp_unsol_cb, ub_spec, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_LINK_CTL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Turn deaf ear on unsolicited link control frames.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Typical unsolicited link control Frame is an LCR
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (to reset End to End credit to the default login
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value and abort current sequences for all classes)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An intelligent microcode/firmware should handle
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this transparently at its level and not pass all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the way up here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Possible responses to LCR are R_RDY, F_RJT, P_RJT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or F_BSY. P_RJT is chosen to be the most appropriate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at this time.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Just reject everything else as an invalid request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_active_ubs > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--(port->fp_active_ubs) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state &= ~FP_SOFT_IN_UNSOL_CB;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, &buf->ub_token);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare a BA_RJT and send it over.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ba_rjt_init(fc_local_port_t *port, fp_cmd_t *cmd, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_ba_rjt_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_LS_BA_RJT, FC_TYPE_BASIC_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.reserved = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.reason_code = FC_REASON_CMD_UNSUPPORTED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.explanation = FC_EXPLN_NONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.vendor = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare an LS_RJT and send it over
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_els_rjt_init(fc_local_port_t *port, fp_cmd_t *cmd, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t action, uchar_t reason, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_rjt_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_ELS_RSP, FC_TYPE_EXTENDED_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.action = action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.reason = reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.reserved = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.vu = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fp_prlo_acc_init
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Initializes an Link Service Accept for a PRLO.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *port Local port through which the PRLO was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * received.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmd Command that will carry the accept.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * *buf Unsolicited buffer containing the PRLO
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * job Job request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sleep Allocation mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: *cmd Command containing the response.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * Context: Depends on the parameter sleep.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_cmd_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_prlo_acc_init(fc_local_port_t *port, fc_remote_port_t *pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_unsol_buf_t *buf, job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_prlo_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = (la_els_prlo_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = (size_t)ntohs(req->payload_length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The payload of the accept to a PRLO has to be the exact match of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the payload of the request (at the exception of the code).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, (int)len, 0, sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fp command was successfully allocated.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_ELS_RSP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_TYPE_EXTENDED_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The code is overwritten for the copy. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->ls_code = LA_ELS_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Response code is set. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = ntohs(req->flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags &= ~SP_RESP_CODE_MASK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags |= SP_RESP_CODE_REQ_EXECUTED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->flags = htons(flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prepare an ACC response to an ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_els_acc_init(fc_local_port_t *port, fp_cmd_t *cmd, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_code_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_ELS_RSP, FC_TYPE_EXTENDED_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code = LA_ELS_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unsolicited PRLO handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A Process Logout should be handled by the ULP that established it. However,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * some devices send a PRLO to trigger a PLOGI followed by a PRLI. This happens
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when a device implicitly logs out an initiator (for whatever reason) and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tries to get that initiator to restablish the connection (PLOGI and PRLI).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The logical thing to do for the device would be to send a LOGO in response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to any FC4 frame sent by the initiator. Some devices choose, however, to send
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a PRLO instead.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * From a Fibre Channel standpoint a PRLO calls for a PRLI. There's no reason to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * think that the Port Login has been lost. If we follow the Fibre Channel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * protocol to the letter a PRLI should be sent after accepting the PRLO. If
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the Port Login has also been lost, the remote port will reject the PRLI
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * indicating that we must PLOGI first. The initiator will then turn around and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * send a PLOGI. The way Leadville is layered and the way the ULP interface
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is defined doesn't allow this scenario to be followed easily. If FCP were to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle the PRLO and attempt the PRLI, the reject indicating that a PLOGI is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * needed would be received by FCP. FCP would have, then, to tell the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (fp) to PLOGI. The problem is, the transport would still think the Port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Login is valid and there is no way for FCP to tell the transport: "PLOGI even
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if you think it's not necessary". To work around that difficulty, the PRLO
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is treated by the transport as a LOGO. The downside to it is a Port Login
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * may be disrupted (if a PLOGI wasn't actually needed) and another ULP (that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has nothing to do with the PRLO) may be impacted. However, this is a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scenario very unlikely to happen. As of today the only ULP in Leadville
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * using PRLI/PRLOs is FCP. For a PRLO to disrupt another ULP (that would be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCIP), a SCSI target would have to be running FCP and FCIP (which is very
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unlikely).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_prlo(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int retain;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte boolean_t tolerance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_prlo_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = (la_els_prlo_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ntohs(req->payload_length) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sizeof (service_parameter_page_t) + sizeof (ls_code_t))) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (req->page_length != sizeof (service_parameter_page_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We are being very restrictive. Only on page per
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * payload. If it is not the case we reject the ELS although
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should reply indicating we handle only single page
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * per PRLO.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_reject_prlo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ntohs(req->payload_length) > buf->ub_bufsize) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is in case the payload advertizes a size bigger than
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * what it really is.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_reject_prlo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy = port->fp_statec_busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tolerance = fctl_tc_increment(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags == PD_ELS_IN_PROGRESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(5, 0), "Logout; D_ID=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pd=%p - busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fp_reject_prlo;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retain = (pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tolerance) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_reset(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retain = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(5, 0), "Accepting LOGO; d_id=%x, pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " tolerance=%d retain=%d", pd->pd_port_id.port_id, pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tolerance, retain);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_LOGGED_OUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_prlo_acc_init(port, pd, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = kmem_zalloc(sizeof (fc_portmap_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (retain) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unregister_login(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s logged out"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %d times in %d us; Giving up", d_id, ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGO_TOLERANCE_LIMIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGO_TOLERANCE_TIME_LIMIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr, pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, listptr, 1, 1, KM_SLEEP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_reject_prlo:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t), 0, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf, FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unsolicited LOGO handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_logo(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int retain;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte boolean_t tolerance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy = port->fp_statec_busy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tolerance = fctl_tc_increment(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags == PD_ELS_IN_PROGRESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(5, 0), "Logout; D_ID=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pd=%p - busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retain = (pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tolerance) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_reset(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retain = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(5, 0), "Accepting LOGO; d_id=%x, pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " tolerance=%d retain=%d", pd->pd_port_id.port_id, pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tolerance, retain);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_LOGGED_OUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, FP_PORT_IDENTIFIER_LEN, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_acc_init(port, cmd, buf, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = kmem_zalloc(sizeof (fc_portmap_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (retain) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when get LOGO, first try to get PID from nameserver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if failed, then we do not need
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * send PLOGI to that remote port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte JOB_NS_CMD, 0, NULL, (opaque_t)port, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pwwn =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret != FC_SUCCESS) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (job->job_result != FC_SUCCESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "NS query failed,",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " delete pd");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto delete_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unregister_login(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t d_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed delete_pd:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s logged out"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %d times in %d us; Giving up", d_id, ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGO_TOLERANCE_LIMIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGO_TOLERANCE_TIME_LIMIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr, pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, listptr, 1, 1, KM_SLEEP, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform general purpose preparation of a response to an unsolicited request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_unsol_resp_init(fc_packet_t *pkt, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t r_ctl, uchar_t type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.r_ctl = r_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.d_id = buf->ub_frame.s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.s_id = buf->ub_frame.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.type = type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_LAST_SEQ | F_CTL_XCHG_CONTEXT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_id = buf->ub_frame.seq_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.df_ctl = buf->ub_frame.df_ctl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = buf->ub_frame.seq_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ox_id = buf->ub_frame.ox_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rx_id = buf->ub_frame.rx_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_comp = fp_unsol_intr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_timeout = FP_ELS_TIMEOUT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pkt->pkt_ub_resp_token = (opaque_t)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Immediate handling of unsolicited FLOGI and PLOGI requests. In the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * early development days of public loop soc+ firmware, numerous problems
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * were encountered (the details are undocumented and history now) which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * led to the birth of this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a pre-allocated unsolicited response packet is free, send out an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * immediate response, otherwise submit the request to the port thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do the deferred processing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_i_handle_unsol_els(fc_local_port_t *port, fc_unsol_buf_t *buf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sent;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int f_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_acc;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logi_t *payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char dww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = port->fp_els_resp_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_acc = (port->fp_statec_busy == 0) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (buf->ub_buffer[0]) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_PLOGI: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int small;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload = (la_els_logi_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte f_port = FP_IS_F_PORT(payload->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte common_service.cmn_features) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte small = fctl_wwn_cmp(&port->fp_service_params.nport_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &payload->nport_ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &payload->nport_ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = (pd->pd_flags == PD_ELS_IN_PROGRESS) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Most likely this means a cross login is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * progress or a device about to be yanked out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only accept the plogi if my wwn is smaller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stop plogi request (if any)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attempt from local side to speedup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the discovery progress.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the pd as PD_PLOGI_RECEPIENT.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (f_port == 0 && small < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient = PD_PLOGI_RECEPIENT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, dww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsol PLOGI received. PD still exists in the "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PWWN list. pd=%p PWWN=%s, sent=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, dww_name, sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (f_port == 0 && small < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: Mark the pd"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " as plogi recipient, pd=%p, PWWN=%s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ", sent=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, dww_name, sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To avoid Login collisions, accept only if my WWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is smaller than the requester (A curious side note
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * would be that this rule may not satisfy the PLOGIs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initiated by the switch from not-so-well known
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports such as 0xFFFC41)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((f_port == 0 && small < 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((small > 0 && do_acc) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_MUST_ACCEPT_D_ID(buf->ub_frame.s_id)) && sent == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_is_class_supported(port->fp_cos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_class) == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_CLASS_NOT_SUPP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsupported class. "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Rejecting PLOGI");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fp_port_id is zero and topology is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Point-to-Point, get the local port id from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the d_id in the PLOGI request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the outgoing FLOGI hasn't been accepted,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the topology will be unknown here. But it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * still safe to save the d_id to fp_port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just because it will be overwritten later
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the topology is not Point-to-Point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_port_id.port_id == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_topology == FC_TOP_PT_PT ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology == FC_TOP_UNKNOWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Sometime later, we should validate
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the service parameters instead of
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * just accepting it.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fp_login_acc_init(port, cmd, buf, NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang KM_NOSLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FP_TRACE(FP_NHEAD1(3, 0),
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "fp_i_handle_unsol_els: Accepting PLOGI,"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang " f_port=%d, small=%d, do_acc=%d,"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang " sent=%d.", f_port, small, do_acc,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options & FP_SEND_RJT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_LOGICAL_BSY, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Rejecting PLOGI with Logical Busy."
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Possible Login collision.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LA_ELS_FLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_is_class_supported(port->fp_cos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_class) == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_CLASS_NOT_SUPP, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsupported Class. Rejecting FLOGI.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_PORT_STATE_MASK(port->fp_state) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_STATE_ONLINE || (port->fp_port_id.port_id &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id == port->fp_port_id.port_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Invalid Link Ctrl. "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Rejecting FLOGI.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let's not aggressively validate the N_Port's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * service parameters until PLOGI. Suffice it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to give a hint that we are an N_Port and we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are game to some serious stuff here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_login_acc_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_i_handle_unsol_els: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Accepting FLOGI.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fp_sendcmd(port, cmd, port->fp_fca_handle)) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_els_resp_pkt_busy = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle unsolicited PLOGI request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_plogi(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sent;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int small;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int f_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_wwn_t *swwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *dwwn;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logi_t *payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char dww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload = (la_els_logi_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte f_port = FP_IS_F_PORT(payload->common_service.cmn_features) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_acc = (port->fp_statec_busy == 0) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_plogi: s_id=%x, d_id=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "type=%x, f_ctl=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " seq_id=%x, ox_id=%x, rx_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ro=%x", buf->ub_frame.s_id, buf->ub_frame.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.type, buf->ub_frame.f_ctl, buf->ub_frame.seq_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.ox_id, buf->ub_frame.rx_id, buf->ub_frame.ro);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte swwn = &port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dwwn = &payload->nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte small = fctl_wwn_cmp(swwn, dwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, dwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = (pd->pd_flags == PD_ELS_IN_PROGRESS) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Most likely this means a cross login is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * progress or a device about to be yanked out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only accept the plogi if my wwn is smaller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stop plogi request (if any)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * attempt from local side to speedup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the discovery progress.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark the pd as PD_PLOGI_RECEPIENT.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (f_port == 0 && small < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient = PD_PLOGI_RECEPIENT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pd->pd_port_name, dww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_plogi: Unsol PLOGI"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " received. PD still exists in the PWWN list. pd=%p "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PWWN=%s, sent=%x", pd, dww_name, sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (f_port == 0 && small < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_handle_unsol_plogi: Mark the pd"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " as plogi recipient, pd=%p, PWWN=%s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ", sent=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, dww_name, sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Avoid Login collisions by accepting only if my WWN is smaller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A side note: There is no need to start a PLOGI from this end in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this context if login isn't going to be accepted for the
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * above reason as either a LIP (in private loop), RSCN (in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fabric topology), or an FLOGI (in point to point - Huh ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check FC-PH) would normally drive the PLOGI from this end.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * At this point of time there is no need for an inbound PLOGI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to kick an outbound PLOGI when it is going to be rejected
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the reason of WWN being smaller. However it isn't hard
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do that either (when such a need arises, start a timer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for a duration that extends beyond a normal device discovery
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * time and check if an outbound PLOGI did go before that, if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none fire one)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unfortunately, as it turned out, during booting, it is possible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to miss another initiator in the same loop as port driver
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * instances are serially attached. While preserving the above
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * comments for belly laughs, please kick an outbound PLOGI in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a non-switch environment (which is a pt pt between N_Ports or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a private loop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * While preserving the above comments for amusement, send an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ACC if the PLOGI is going to be rejected for WWN being smaller
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when no discovery is in progress at this end. Turn around
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and make the port device as the PLOGI initiator, so that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * during subsequent link/loop initialization, this end drives
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the PLOGI (In fact both ends do in this particular case, but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only one wins)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure the PLOGIs initiated by the switch from not-so-well-known
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports (such as 0xFFFC41) are accepted too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((f_port == 0 && small < 0) || (((small > 0 && do_acc) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_MUST_ACCEPT_D_ID(buf->ub_frame.s_id)) && sent == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_is_class_supported(port->fp_cos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_class) == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_els_logi_t), 0, sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_CLASS_NOT_SUPP, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_handle_unsol_plogi: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unsupported class. rejecting PLOGI");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_logi_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sometime later, we should validate the service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameters instead of just accepting it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_login_acc_init(port, cmd, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_plogi: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Accepting PLOGI, f_port=%d, small=%d, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "do_acc=%d, sent=%d.", f_port, small, do_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fp_port_id is zero and topology is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Point-to-Point, get the local port id from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the d_id in the PLOGI request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the outgoing FLOGI hasn't been accepted,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the topology will be unknown here. But it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * still safe to save the d_id to fp_port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just because it will be overwritten later
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if the topology is not Point-to-Point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_port_id.port_id == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (port->fp_topology == FC_TOP_PT_PT ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_topology == FC_TOP_UNKNOWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_port_id.port_id =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options & FP_SEND_RJT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_cmdlen = sizeof (la_els_rjt_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_rsplen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send out Logical busy to indicate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the detection of PLOGI collision
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_LOGICAL_BSY, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(dwwn, dww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_plogi: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Rejecting Unsol PLOGI with Logical Busy."
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "possible PLOGI collision. PWWN=%s, sent=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dww_name, sent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle mischievous turning over of our own FLOGI requests back to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * us by the SOC+ microcode. In other words, look at the class of such
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bone headed requests, if 1 or 2, bluntly P_RJT them, if 3 drop them
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the floor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_flogi(fc_local_port_t *port, fc_unsol_buf_t *buf,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_is_class_supported(port->fp_cos, buf->ub_class) == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_CLASS_NOT_SUPP, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_flogi:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " s_id=%x, d_id=%x, type=%x, f_ctl=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " seq_id=%x, ox_id=%x, rx_id=%x, ro=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id, buf->ub_frame.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.type, buf->ub_frame.f_ctl,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.seq_id, buf->ub_frame.ox_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.rx_id, buf->ub_frame.ro);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = FC_PORT_STATE_MASK(port->fp_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state != FC_STATE_ONLINE ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (s_id && buf->ub_frame.s_id == s_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_handle_unsol_flogi: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Rejecting PLOGI. Invalid Link CTRL");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let's not aggressively validate the N_Port's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * service parameters until PLOGI. Suffice it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to give a hint that we are an N_Port and we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are game to some serious stuff here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_login_acc_init(port, cmd, buf, job, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_flogi: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Accepting PLOGI");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform PLOGI accept
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_login_acc_init(fc_local_port_t *port, fp_cmd_t *cmd, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_logi_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(buf != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we are sending ACC to PLOGI and we haven't already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create port and node device handles, let's create them
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_buffer[0] == LA_ELS_PLOGI &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_IS_REAL_DEVICE(buf->ub_frame.s_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int small;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_acc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed la_els_logi_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = (la_els_logi_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte small = fctl_wwn_cmp(&port->fp_service_params.nport_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &req->nport_ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_acc = (port->fp_statec_busy == 0) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(3, 0), "fp_plogi_acc_init fp %x, pd %x",
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, buf->ub_frame.s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_create_remote_port(port, &req->node_ww_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &req->nport_ww_name, buf->ub_frame.s_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_RECEPIENT, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "login_acc_init: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Couldn't create port device for d_id:0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "couldn't create port device d_id=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * usoc currently returns PLOGIs inline and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the maximum buffer size is 60 bytes or so.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So attempt not to look beyond what is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the unsolicited buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * JNI also traverses this path sometimes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf->ub_bufsize >= sizeof (la_els_logi_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_register_login(NULL, pd, req, buf->ub_class);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_login_count == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_LOGGED_IN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_class = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = kmem_zalloc(sizeof (fc_portmap_t), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listptr != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, listptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 1, 1, sleep, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (small > 0 && do_acc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient = PD_PLOGI_INITIATOR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_ELS_RSP, FC_TYPE_EXTENDED_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload = port->fp_service_params;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "login_acc_init: ELS:0x%x d_id:0x%x "
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed "bufsize:0x%x sizeof (la_els_logi):0x%x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port's wwn:0x%01x%03x%04x%08x requestor's wwn:0x%01x%03x%04x%08x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "statec_busy:0x%x", buf->ub_buffer[0], buf->ub_frame.s_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_bufsize, sizeof (la_els_logi_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.w.naa_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.w.nport_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.w.wwn_hi,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.w.wwn_lo,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((la_els_logi_t *)buf->ub_buffer)->nport_ww_name.w.naa_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((la_els_logi_t *)buf->ub_buffer)->nport_ww_name.w.nport_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((la_els_logi_t *)buf->ub_buffer)->nport_ww_name.w.wwn_hi,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((la_els_logi_t *)buf->ub_buffer)->nport_ww_name.w.wwn_lo,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RSCN_EVENT_NAME_LEN 256
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle RSCNs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_rscn(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int listindex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int16_t len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_rscn_t *payload;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_affected_id_t *page;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t nvname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_t *attr_list = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, FP_PORT_IDENTIFIER_LEN, 0, sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_acc_init(port, cmd, buf, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload = (fc_rscn_t *)buf->ub_buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(payload->rscn_code == LA_ELS_RSCN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(payload->rscn_len == FP_PORT_IDENTIFIER_LEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = payload->rscn_payload_len - FP_PORT_IDENTIFIER_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len <= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((len & 0x3) == 0); /* Must be power of 4 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = (len >> 2) << 1; /* number of pages multiplied by 2 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = kmem_zalloc(sizeof (fc_portmap_t) * count, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page = (fc_affected_id_t *)(buf->ub_buffer + sizeof (fc_rscn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gpn_id_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gpn_id_t), sizeof (ns_resp_gpn_id_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(listptr, sizeof (fc_portmap_t) * count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GPN_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_handle_unsol_rscn: s_id=%x, d_id=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "type=%x, f_ctl=%x seq_id=%x, ox_id=%x, rx_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ro=%x", buf->ub_frame.s_id, buf->ub_frame.d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.type, buf->ub_frame.f_ctl, buf->ub_frame.seq_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf->ub_frame.ox_id, buf->ub_frame.rx_id, buf->ub_frame.ro);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Only proceed if we can allocate nvname and the nvlist */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nvname = kmem_zalloc(RSCN_EVENT_NAME_LEN, KM_NOSLEEP)) != NULL &&
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE,
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed KM_NOSLEEP) == DDI_SUCCESS) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (!(attr_list && nvlist_add_uint32(attr_list, "instance",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance) == DDI_SUCCESS &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_add_byte_array(attr_list, "port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t)) == DDI_SUCCESS)) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed nvlist_free(attr_list);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed attr_list = NULL;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (listindex = 0; len; len -= FP_PORT_IDENTIFIER_LEN, page++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Add affected page to the event payload */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr_list != NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (void) snprintf(nvname, RSCN_EVENT_NAME_LEN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "affected_page_%d", listindex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed if (attr_list && nvlist_add_uint32(attr_list, nvname,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ntohl(*(uint32_t *)page)) != DDI_SUCCESS) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed /* We don't send a partial event, so dump it */
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed nvlist_free(attr_list);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed attr_list = NULL;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Query the NS to get the Port WWN for this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * affected D_ID.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mask = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (page->aff_format & FC_RSCN_ADDRESS_MASK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RSCN_PORT_ADDRESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_validate_rscn_page(port, page, job, ns_cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr, &listindex, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listindex == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We essentially did not process this RSCN. So,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULPs are not going to be called and so we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * decrement the rscn_count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RSCN_AREA_ADDRESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mask = 0xFFFF00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RSCN_DOMAIN_ADDRESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!mask) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mask = 0xFF0000;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_validate_area_domain(port, page->aff_d_id, mask,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RSCN_FABRIC_ADDRESS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to discover all the devices on this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_validate_area_domain(port, 0, 0, job, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (attr_list != NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (void) ddi_log_sysevent(port->fp_port_dip, DDI_VENDOR_SUNW,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EC_SUNFC, ESC_SUNFC_PORT_RSCN, attr_list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, DDI_SLEEP);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed FP_TRACE(FP_NHEAD1(9, 0),
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed "RSCN handled, but event not sent to userland");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvname != NULL) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed kmem_free(nvname, RSCN_EVENT_NAME_LEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listindex) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page = (fc_affected_id_t *)(buf->ub_buffer +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_rscn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listptr->map_did.port_id != page->aff_d_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PORT RSCN: processed=%x, reporting=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_did.port_id, page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, listptr, listindex, count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(listptr, sizeof (fc_portmap_t) * count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill out old map for ULPs with fp_mutex, fd_mutex and pd_mutex held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_old_map_held(fc_portmap_t *map, fc_remote_port_t *pd, uchar_t flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int is_switch;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This function has the following bunch of assumptions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_remote_nodep->fd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator = (pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte is_switch = FC_IS_TOP_SWITCH(port->fp_topology);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "fp_fillout_old_map_held: port=%p, d_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " removed the PD=%p from DID and PWWN tables",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, pd->pd_port_id.port_id, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!flag) && port && initiator && is_switch) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan_held(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap_held(map, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill out old map for ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_old_map(fc_portmap_t *map, fc_remote_port_t *pd, uchar_t flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int is_switch;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator = (pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte is_switch = FC_IS_TOP_SWITCH(port->fp_topology);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "fp_fillout_old_map: port=%p, d_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " removed the PD=%p from DID and PWWN tables",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, pd->pd_port_id.port_id, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!flag) && port && initiator && is_switch) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan(port, pd, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(map, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fillout Changed Map for ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_changed_map(fc_portmap_t *map, fc_remote_port_t *pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *new_did, la_wwn_t *new_pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_did) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id = *new_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_pwwn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name = *new_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(map, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fillout New Name Server map
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fillout_new_nsmap(fc_local_port_t *port, ddi_acc_handle_t *handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *port_map, ns_resp_gan_t *gan_resp, uint32_t d_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (handle) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)&port_map->map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_pwwn, sizeof (gan_resp->gan_pwwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)&port_map->map_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_nwwn, sizeof (gan_resp->gan_nwwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)port_map->map_fc4_types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (gan_resp->gan_fc4types), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&gan_resp->gan_pwwn, &port_map->map_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (gan_resp->gan_pwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&gan_resp->gan_nwwn, &port_map->map_nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (gan_resp->gan_nwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(gan_resp->gan_fc4types, port_map->map_fc4_types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (gan_resp->gan_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_did.port_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_did.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_hard_addr.hard_addr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_hard_addr.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_map->map_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_remove_if_orphan(port, &port_map->map_pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform LINIT ELS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_remote_lip(fc_local_port_t *port, la_wwn_t *pwwn, int sleep,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t lfa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_porttype_t ptype;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_linit_req_t payload;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t), sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)(ns_cmd->ns_cmd_buf))->pwwn = *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job, 1, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS || job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ns_cmd->ns_data_buf, (caddr_t)&d_id, sizeof (d_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = BE_32(*((uint32_t *)ns_cmd->ns_data_buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lfa = d_id & 0xFFFF00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given this D_ID, get the port type to see if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we can do LINIT on the LFA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gpt_id_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gpt_id_t), sizeof (ns_resp_gpt_id_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GPT_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gpt_id_t *)(ns_cmd->ns_cmd_buf))->pid.port_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gpt_id_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job, 1, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS || job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ns_cmd->ns_data_buf, (caddr_t)&ptype, sizeof (ptype));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ptype.port_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_NL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_F_NL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_FL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ptype = pd->pd_porttype;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (pd->pd_porttype.port_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_NL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_F_NL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NS_PORT_FL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lfa = pd->pd_port_id.port_id & 0xFFFF00;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port->fp_ns_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_linit_req_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_linit_resp_t), sleep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_init(cmd, s_id, lfa, fp_linit_intr, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * How does LIP work by the way ?
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * If the L_Port receives three consecutive identical ordered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sets whose first two characters (fully decoded) are equal to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the values shown in Table 3 of FC-AL-2 then the L_Port shall
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * recognize a Loop Initialization Primitive sequence. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * character 3 determines the type of lip:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LIP(F7) Normal LIP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LIP(F8) Loop Failure LIP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The possible combination for the 3rd and 4th bytes are:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * F7, F7 Normal Lip - No valid AL_PA
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * F8, F8 Loop Failure - No valid AL_PA
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * F7, AL_PS Normal Lip - Valid source AL_PA
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * F8, AL_PS Loop Failure - Valid source AL_PA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * AL_PD AL_PS Loop reset of AL_PD originated by AL_PS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * And Normal Lip for all other loop members
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0xFF AL_PS Vendor specific reset of all loop members
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now, it may not always be that we, at the source, may have an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * AL_PS (AL_PA of source) for 4th character slot, so we decide
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do (Normal Lip, No Valid AL_PA), that means, in the LINIT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * payload we are going to set:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lip_b3 = 0xF7; Normal LIP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lip_b4 = 0xF7; No valid source AL_PA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_LINIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.func = 0; /* Let Fabric determine the best way */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.lip_b3 = 0xF7; /* Normal LIP */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.lip_b4 = 0xF7; /* No valid source AL_PA */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fill out the device handles with GAN response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_stuff_device_with_gan(ddi_acc_handle_t *handle, fc_remote_port_t *pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_resp_gan_t *gan_resp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_porttype_t type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(handle != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "GAN PD stuffing; pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " port_id=%x, sym_len=%d fc4-type=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, gan_resp->gan_type_id.rsvd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_spnlen, gan_resp->gan_fc4types[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)&type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_type_id, sizeof (type), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_porttype.port_type = type.port_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_porttype.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_spn_len = gan_resp->gan_spnlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_spn_len) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)pd->pd_spn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_spname, pd->pd_spn_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)pd->pd_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_ip, sizeof (pd->pd_ip_addr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)&pd->pd_cos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_cos, sizeof (pd->pd_cos),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)pd->pd_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_fc4types, sizeof (pd->pd_fc4types),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)node->fd_ipa,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_ipa, sizeof (node->fd_ipa),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node->fd_snn_len = gan_resp->gan_snnlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node->fd_snn_len) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, *handle, (uint8_t *)node->fd_snn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_snname, node->fd_snn_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handles all NS Queries (also means that this function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * doesn't handle NS object registration)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_query(fc_local_port_t *port, fctl_ns_req_t *ns_cmd, job_request_t *job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int polled, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China if (ns_cmd->ns_cmd_code == NS_GA_NXT) {
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(1, 0), "fp_ns_query GA_NXT fp %x pd %x",
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, ns_cmd->ns_gan_sid);
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China }
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_size == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_size, sizeof (fc_ct_header_t) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_size, sleep, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ct_init(port, cmd, ns_cmd, ns_cmd->ns_cmd_code, ns_cmd->ns_cmd_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_size, ns_cmd->ns_resp_size, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (polled) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (polled == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return FC_SUCCESS to indicate that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_iodone is performed already.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (polled) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize Common Transport request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ct_init(fc_local_port_t *port, fp_cmd_t *cmd, fctl_ns_req_t *ns_cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t cmd_code, caddr_t cmd_buf, uint16_t cmd_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t resp_len, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t class;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_packet_t *pkt;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_ct_header_t ct;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port->fp_ns_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_private = ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_rev = CT_REV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_inid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_fcstype = FCSTYPE_DIRECTORY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_fcssubtype = FCSSUB_DS_NAME_SERVER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_options = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_reserved1 = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_cmdrsp = cmd_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_aiusize = resp_len >> 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_reserved2 = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_reason = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_expln = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct.ct_vendor = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&ct,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint8_t *)pkt->pkt_cmd, sizeof (ct), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.d_id = 0xFFFFFC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.s_id = s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_SEQ_INITIATIVE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_cmd_fhdr.rsvd = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_comp = fp_ns_intr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_ulp_private = (opaque_t)cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_timeout = FP_NS_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_buf) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)cmd_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_transport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_PLOGI_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = fp_retry_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Name Server request interrupt routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_intr(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_ct_header_t resp_hdr;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_ct_header_t cmd_hdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds--;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_cmd_acc, (uint8_t *)&cmd_hdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (cmd_hdr), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = (fctl_ns_req_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((fp_cmd_t *)(pkt->pkt_ulp_private))->cmd_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FP_IS_PKT_ERROR(pkt)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&resp_hdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_resp, sizeof (resp_hdr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * On x86 architectures, make sure the resp_hdr is big endian.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This macro is a NOP on sparc architectures mainly because
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we don't want to end up wasting time since the end result
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is going to be the same.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MAKE_BE_32(&resp_hdr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Always copy out the response CT_HDR
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&resp_hdr, &ns_cmd->ns_resp_hdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (resp_hdr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp_hdr.ct_cmdrsp == FS_RJT_IU) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_FS_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = resp_hdr.ct_reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_expln = resp_hdr.ct_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_PKT_ERROR(pkt)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_VALIDATE_PD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd->ns_pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Mark it OLD if not already done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ns_cmd->ns_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ns_cmd->ns_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_ASYNC_REQUEST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fp_cmd_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pkt->pkt_ulp_private))->cmd_private = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8eec3430a514cd7c4e568f6dbe40d81b2f8f2d27Rijawanemohammadhusen Nadaf FP_TRACE(FP_NHEAD2(1, 0), "%x NS failure pkt state=%x "
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China "reason=%x, expln=%x, NSCMD=%04X, NSRSP=%04X",
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, pkt->pkt_state,
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China pkt->pkt_reason, pkt->pkt_expln,
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China cmd_hdr.ct_cmdrsp, resp_hdr.ct_cmdrsp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_common_intr(pkt, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (resp_hdr.ct_cmdrsp != FS_ACC_IU) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pkt->pkt_cmd_fhdr.d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Bogus NS response received for D_ID=%x", d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_hdr.ct_cmdrsp == NS_GA_NXT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_gan_handler(pkt, ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_hdr.ct_cmdrsp >= NS_GPN_ID &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_hdr.ct_cmdrsp <= NS_GID_PT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ns_cmd->ns_flags & FCTL_NS_NO_DATA_BUF) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_ns_query_handler(pkt, ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(pkt->pkt_ulp_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Process NS_GAN response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_gan_handler(fc_packet_t *pkt, fctl_ns_req_t *ns_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int my_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portid_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req_gan_t gan_req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_resp_gan_t *gan_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp = (ns_resp_gan_t *)(pkt->pkt_resp + sizeof (fc_ct_header_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_type_id, sizeof (d_id), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(uint32_t *)&d_id = BE_32(*(uint32_t *)&d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In this case the priv_lilp_posit field in reality
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is actually represents the relative position on a private loop.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So zero it while dealing with Port Identifiers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_gan_sid == d_id.port_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We've come a full circle; time to get out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_gan_sid == FCTL_GAN_START_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = d_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte my_did = (d_id.port_id == port->fp_port_id.port_id) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(1, 0), "GAN response; port=%p, fp %x pd %x", port,
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China port->fp_port_id.port_id, d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (my_did == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "GAN response details; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port=%p, d_id=%x, type_id=%x, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "pwwn=%x %x %x %x %x %x %x %x, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nwwn=%x %x %x %x %x %x %x %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, d_id.port_id, gan_resp->gan_type_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[2],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[5],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[6],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_pwwn.raw_wwn[7],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[2],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[5],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[6],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_resp->gan_nwwn.raw_wwn[7]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&nwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_nwwn, sizeof (nwwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc, (uint8_t *)&pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)&gan_resp->gan_pwwn, sizeof (pwwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_CREATE_DEVICE && pd == NULL) {
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China FP_TRACE(FP_NHEAD1(1, 0), "fp %x gan_hander create"
e795a287dc7ecf08c8cf000bf39702852f6b6c03duo liu - Sun Microsystems - Beijing China "pd %x", port->fp_port_id.port_id, d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_create_remote_port(port, &nwwn, &pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id.port_id, PD_PLOGI_INITIATOR, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_stuff_device_with_gan(&pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, gan_resp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_GET_DEV_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *((int *)ns_cmd->ns_data_buf) += 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_FILL_NS_MAP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((ns_cmd->ns_flags & FCTL_NS_NO_DATA_BUF) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_BUF_IS_USERLAND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_dev_t *userbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf = ((fc_port_dev_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_did = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)userbuf->dev_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)gan_resp->gan_fc4types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (userbuf->dev_type),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_nwwn = nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_hard_addr =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte userbuf->dev_state =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ns_cmd->ns_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_BUF_IS_FC_PORTMAP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map = ((fc_portmap_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * First fill it like any new map
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and update the port device info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * below.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_new_nsmap(port, &pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map, gan_resp, d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(map, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t dst_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dst_ptr = ns_cmd->ns_data_buf +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (NS_GAN_RESP_LEN) * ns_cmd->ns_gan_index++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)dst_ptr, (uint8_t *)gan_resp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_GAN_RESP_LEN, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_gan_index >= ns_cmd->ns_gan_max) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gan_req.pid = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&gan_req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)(pkt->pkt_cmd + sizeof (fc_ct_header_t)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (gan_req), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_transport(port->fp_fca_handle, pkt) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_TRAN_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed } else {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_enter(&port->fp_mutex);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed port->fp_out_fpcmds++;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle NS Query interrupt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_query_handler(fc_packet_t *pkt, fctl_ns_req_t *ns_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed caddr_t src_ptr;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t xfer_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = pkt->pkt_ulp_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xfer_len = ns_cmd->ns_resp_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "NS Query response, cmd_code=%x, xfer_len=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code, xfer_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_code == NS_GPN_ID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_ptr = (caddr_t)pkt->pkt_resp + sizeof (fc_ct_header_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "GPN_ID results; %x %x %x %x %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (xfer_len <= ns_cmd->ns_data_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_ptr = (caddr_t)pkt->pkt_resp + sizeof (fc_ct_header_t);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_GET_RSP(port, pkt->pkt_resp_acc,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint8_t *)ns_cmd->ns_data_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)src_ptr, xfer_len, DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_VALIDATE_PD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd->ns_pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ns_cmd->ns_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ns_cmd->ns_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_flags & FCTL_NS_ASYNC_REQUEST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fp_cmd_t *)(pkt->pkt_ulp_private))->cmd_private = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle unsolicited ADISC ELS request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_handle_unsol_adisc(fc_local_port_t *port, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(5, 0), "ADISC; port=%p, D_ID=%x state=%x, pd=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, pd->pd_port_id.port_id, pd->pd_state, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FP_IS_CLASS_1_OR_2(buf->ub_class)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_rjt_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_els_rjt_init(port, cmd, buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_ACTION_NON_RETRYABLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_REASON_INVALID_LINK_CTRL, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Yes, yes, we don't have a hard address. But we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should still respond. Huh ? Visit 21.19.2
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of FC-PH-2 which essentially says that if an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NL_Port doesn't have a hard address, or if a port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * does not have FC-AL capability, it shall report
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zeroes in this field.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_adisc_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_adisc_acc_init(port, cmd, buf, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize ADISC response.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_adisc_acc_init(fc_local_port_t *port, fp_cmd_t *cmd, fc_unsol_buf_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_adisc_t payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = buf->ub_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_OUTBOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_CFLAG_UNDEFINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_transport = port->fp_fca_tran->fca_els_send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_job = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = &cmd->cmd_pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_resp_init(pkt, buf, R_CTL_ELS_RSP, FC_TYPE_EXTENDED_LS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.ls_code = LA_ELS_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.nport_id = port->fp_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.hard_addr = port->fp_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.port_wwn = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte payload.node_wwn = port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_SET_CMD(port, pkt->pkt_cmd_acc, (uint8_t *)&payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t *)pkt->pkt_cmd, sizeof (payload), DDI_DEV_AUTOINCR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hold and Install the requested ULP drivers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_load_ulp_modules(dev_info_t *dip, fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int data_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte major_t ulp_major;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t ulp_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t data_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t data_buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data_buf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS, "load-ulp-list",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&data_buf, &data_len) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(data_buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ulp_nload = fctl_atoi(data_buf, 10);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data_ptr = data_buf + len + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < port->fp_ulp_nload; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = strlen(data_ptr) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_name = kmem_zalloc(len, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(data_ptr, ulp_name, len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_major = ddi_name_to_major(ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_major != (major_t)-1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (modload("drv", ulp_name) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, NULL, "failed to load %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s isn't a valid driver", ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ulp_name, len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data_ptr += len; /* Skip to next field */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Free the memory allocated by DDI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (data_buf != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(data_buf, data_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform LOGO operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_logout(fc_local_port_t *port, fc_remote_port_t *pd, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logo_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PORT_IDENTIFIER_LEN, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_state == PORT_DEVICE_LOGGED_IN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_login_count == 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logo_init(pd, cmd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_sendcmd(port, cmd, port->fp_fca_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_iodone(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform Port attach callbacks to registered ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_attach_ulps(fc_local_port_t *port, fc_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_soft_attach_t *att;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att = kmem_zalloc(sizeof (*att), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att->att_cmd = cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att->att_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to remember whether or not fctl_busy_port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * succeeded so we know whether or not to call
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_idle_port when the task is complete.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_busy_port(port) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att->att_need_pm_idle = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att->att_need_pm_idle = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) taskq_dispatch(port->fp_taskq, fp_ulp_port_attach,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte att, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Forward state change notifications on to interested ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Spawns a call to fctl_ulp_statec_cb() in a taskq thread to do all the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * real work.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ulp_notify(fc_local_port_t *port, uint32_t statec, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_port_clist_t *clist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist = kmem_zalloc(sizeof (*clist), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_state = statec;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_flags = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_port = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_size = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) taskq_dispatch(port->fp_taskq, fctl_ulp_statec_cb,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get name server map
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_getmap(fc_local_port_t *port, job_request_t *job, fc_portmap_t **map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *len, uint32_t sid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Don't let the allocator do anything for response;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we have have buffer ready to fillout.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gan_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gan_t), 0, (FCTL_NS_FILL_NS_MAP |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_BUF_IS_FC_PORTMAP), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_len = sizeof (**map) * (*len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf = (caddr_t)*map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GA_NXT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_max = *len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_gan_index != *len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = ns_cmd->ns_gan_index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a remote port in Fabric topology by using NS services
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_create_remote_port_by_ns(fc_local_port_t *port, uint32_t d_id, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed job_request_t *job;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "PD creation begin; port=%p, d_id=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(FC_IS_TOP_SWITCH(port->fp_topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_NS_CMD, 0, NULL, (opaque_t)port, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gan_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gan_t), 0, (FCTL_NS_CREATE_DEVICE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_NO_DATA_BUF), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_max = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GA_NXT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_gan_sid = FCTL_GAN_START_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gan_t *)(ns_cmd->ns_cmd_buf))->pid.port_id = d_id - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gan_t *)(ns_cmd->ns_cmd_buf))->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS || job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "PD creation end; port=%p, d_id=%x, pd=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, d_id, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check for the permissions on an ioctl command. If it is required to have an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * EXCLUSIVE open performed, return a FAILURE to just shut the door on it. If
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the ioctl command isn't in one of the list built, shut the door on that too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * Certain ioctls perform hardware accesses in FCA drivers, and it needs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to be made sure that users open the port for an exclusive access while
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * performing those operations.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed * This can prevent a casual user from inflicting damage on the port by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sending these ioctls from multiple processes/threads (there is no good
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reason why one would need to do that) without actually realizing how
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * expensive such commands could turn out to be.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is also important to note that, even with an exclusive access,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * multiple threads can share the same file descriptor and fire down
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * commands in parallel. To prevent that the driver needs to make sure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that such commands aren't in progress already. This is taken care of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the FP_EXCL_BUSY bit of fp_flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_check_perms(uchar_t open_flag, uint16_t ioctl_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count < sizeof (fp_perm_list) / sizeof (fp_perm_list[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_perm_list[count].fp_ioctl_cmd == ioctl_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_perm_list[count].fp_open_flag & open_flag) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Bind Port driver's unsolicited, state change callbacks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_bind_callbacks(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_bind_info_t bind_info = {0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_info_t *port_info;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int node_namelen, port_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *nname = NULL, *pname = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_lookup_string(DDI_DEV_T_ANY, port->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "node-name", &nname) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_bind_callback fail to get node-name");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nname) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_str_to_wwn(nname, &(bind_info.port_nwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_lookup_string(DDI_DEV_T_ANY, port->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port-name", &pname) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_bind_callback fail to get port-name");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pname) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_str_to_wwn(pname, &(bind_info.port_pwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_npiv_type == FC_NPIV_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bind_info.port_npiv = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fca_bind_port returns the FCA driver's handle for the local
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port instance. If the port number isn't supported it returns NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It also sets up callback in the FCA for various
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * things like state change, ELS etc..
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bind_info.port_statec_cb = fp_statec_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bind_info.port_unsol_cb = fp_unsol_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bind_info.port_num = port->fp_port_num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bind_info.port_handle = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_info = kmem_zalloc(sizeof (*port_info), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hold the port driver mutex as the callbacks are bound until the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * service parameters are properly filled in (in order to be able to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * properly respond to unsolicited ELS requests)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle = port->fp_fca_tran->fca_bind_port(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_dip, port_info, &bind_info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_fca_handle == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = DDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto exit;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Only fcoei will set this bit
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (port_info->pi_port_state & FC_STATE_FCA_IS_NODMA) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_soft_state |= FP_SOFT_FCA_IS_NODMA;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port_info->pi_port_state &= ~(FC_STATE_FCA_IS_NODMA);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_bind_state = port->fp_state = port_info->pi_port_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params = port_info->pi_login_params;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_hard_addr = port_info->pi_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Copy from the FCA structure to the FP structure */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_hba_port_attrs = port_info->pi_attrs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port_info->pi_rnid_params.status == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_rnid_init = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port_info->pi_rnid_params.params,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &port->fp_rnid_params,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_rnid_params));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_rnid_init = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node_namelen = strlen((char *)&port_info->pi_attrs.sym_node_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node_namelen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port_info->pi_attrs.sym_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &port->fp_sym_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_namelen = node_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_namelen = strlen((char *)&port_info->pi_attrs.sym_port_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port_namelen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&port_info->pi_attrs.sym_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &port->fp_sym_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_namelen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_namelen = port_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* zero out the normally unused fields right away */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.ls_code.mbz = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.ls_code.ls_code = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&port->fp_service_params.reserved,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (port->fp_service_params.reserved));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port_info->pi_login_params.class_1.class_opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_cos |= (class & 0x8000) ? FC_NS_CLASS1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port_info->pi_login_params.class_2.class_opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_cos |= (class & 0x8000) ? FC_NS_CLASS2 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte class = port_info->pi_login_params.class_3.class_opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_cos |= (class & 0x8000) ? FC_NS_CLASS3 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteexit:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nname) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_free(nname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pname) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_free(pname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(port_info, sizeof (*port_info));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Retrieve FCA capabilities
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_retrieve_caps(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int ub_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fcp_dma_t fcp_dma;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_reset_action_t action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_dma_behavior_t dma_behavior;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_get_cap(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_CAP_UNSOL_BUF, &ub_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CAP_FOUND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CAP_SETTABLE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ub_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 0:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case -1:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_count = fp_unsol_buf_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 1/4th of total buffers is my share */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ub_count / port->fp_fca_tran->fca_numports) >> 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_ub_count = ub_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_get_cap(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_CAP_POST_RESET_BEHAVIOR, &action);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CAP_FOUND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CAP_SETTABLE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (action) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_RETURN_NONE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_RETURN_ALL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_RETURN_OUTSTANDING:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte action = FC_RESET_RETURN_NONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte action = FC_RESET_RETURN_NONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_reset_action = action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_get_cap(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_CAP_NOSTREAM_ON_UNALIGN_BUF, &dma_behavior);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rval) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CAP_FOUND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (dma_behavior) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ALLOW_STREAMING:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NO_STREAMING:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If capability was found and the value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was incorrect assume the worst
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dma_behavior = FC_NO_STREAMING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If capability was not defined - allow streaming; existing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCAs should not be affected.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dma_behavior = FC_ALLOW_STREAMING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dma_behavior = dma_behavior;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_get_cap(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_CAP_FCP_DMA, &fcp_dma);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_CAP_FOUND || (fcp_dma != FC_NO_DVMA_SPACE &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcp_dma != FC_DVMA_SPACE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcp_dma = FC_DVMA_SPACE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fcp_dma = fcp_dma;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle Domain, Area changes in the Fabric.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_validate_area_domain(fc_local_port_t *port, uint32_t id, uint32_t mask,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t dcnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int send;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int listindex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int login;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int job_flags;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *list;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *norp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *prev;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *npd;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed struct pwwn_hash *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t), sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to get a new count of devices from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * name server, which will also create any new devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as needed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ns_get_devcount(port, job, 1, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp_validate_area_domain: get_devcount found %d devices",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags != PD_ELS_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_port_id.port_id & mask) == id &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient == PD_PLOGI_INITIATOR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_MARK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dcnt = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since port->fp_orphan_count is declared an 'int' it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * theoretically possible that the count could go negative.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This would be bad and if that happens we really do want
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to know.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_orphan_count >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count += port->fp_orphan_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We add the port->fp_total_devices value to the count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the case where our port is newly attached. This is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * because we haven't done any discovery and we don't have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any orphans in the port's orphan list. If we do not do
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this addition to count then we won't alloc enough kmem
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to do discovery with.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (count == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count += port->fp_total_devices;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "fp_validate_area_domain: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "0x%x orphans found, using 0x%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count, count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate the change list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = kmem_zalloc(sizeof (fc_portmap_t) * count, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_printf(port, CE_NOTE, FP_LOG_ONLY, 0, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Not enough memory to service RSCNs"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " for %d ports, continuing...", count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Attempt to validate or invalidate the devices that were
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * already in the pwwn hash table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (listindex = 0, index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((pd = npd) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_port_id.port_id & mask) == id &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags == PD_ELS_MARK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ns_cmd->ns_cmd_buf))->pwwn =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "AREA RSCN: PD disappeared; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "d_id=%x, PWWN=%s", d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " PWWN=%s disappeared from fabric",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(list + listindex++,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(list + listindex++,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(listindex == dcnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = listindex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_flags = job->job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags |= JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Login (if we were the initiator) or validate devices in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port map.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < listindex; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = list[index].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((pd->pd_port_id.port_id & mask) == id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags != PD_ELS_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_type == PORT_DEVICE_OLD);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte login = (pd->pd_state == PORT_DEVICE_LOGGED_IN) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte send = (pd->pd_recepient == PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((d_id & mask) == id && send) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (login) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "RSCN and PLOGI request;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pd=%p, job=%p d_id=%x, index=%d", pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, d_id, index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, sleep, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
32f2f513dbd672742ea1b0e27bff6940a45fdb08Raghuram Prahlada FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI succeeded:no skip(1) for "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "D_ID %x", d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list[index].map_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN and NS request;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pd=%p, job=%p d_id=%x, index=%d", pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job, d_id, index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_validate_device(port, pd, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "RSCN and NO request sent; pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " d_id=%x, index=%d", pd, d_id, index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobdone(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listindex) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags = job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Orphan list validation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (prev = NULL, orp = port->fp_orphan_list; port->fp_orphan_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp != NULL; orp = norp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte norp = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((job->job_flags & JOB_TYPE_FP_ASYNC) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)ns_cmd->ns_cmd_buf)->pwwn = orp->orp_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)ns_cmd->ns_data_buf)->pid.port_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf)->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = BE_32(*((uint32_t *)ns_cmd->ns_data_buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fp_create_remote_port_by_ns(port, d_id, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&orp->orp_pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "RSCN and ORPHAN list "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "success; d_id=%x, PWWN=%s", d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(6, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s reappeared"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " in fabric", d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->orp_next = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(orp == port->fp_orphan_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(orp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(list + listindex++, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * One more pass through the list to delist old devices from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the d_id and pwwn tables and possibly add to the orphan list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < listindex; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = list[index].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update PLOGI results; For NS validation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of orphan list, it is redundant
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Take care to preserve PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appropriate as fctl_copy_portmap() will clear map_flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list[index].map_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(list + index, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list[index].map_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(list + index, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with Area DOMAIN "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "results; pd=%p, d_id=%x pwwn=%x %x %x %x %x %x %x %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[2],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[5],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[6],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name.raw_wwn[7]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with Area DOMAIN "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "results continued, pd=%p type=%x, flags=%x, state=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd, pd->pd_type, pd->pd_flags, pd->pd_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator = (pd->pd_recepient ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (initiator) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan(port, pd, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list[index].map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_flags == PD_IDLE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset LOGO tolerance to zero
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_reset(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listindex) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, list, listindex, count,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(list, sizeof (*list) * count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (--port->fp_rscn_count == FC_INVALID_RSCN_COUNT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Work hard to make sense out of an RSCN page.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_validate_rscn_page(fc_local_port_t *port, fc_affected_id_t *page,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, fctl_ns_req_t *ns_cmd, fc_portmap_t *listptr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *listindex, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pwwn_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *did_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd = fctl_get_remote_port_by_did(port, page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port=%p, d_id=%x, pd=%p, rscn_count:0x%x", port, page->aff_d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd, (uint32_t)(uintptr_t)job->job_cb_arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (did_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (did_pd->pd_flags != PD_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PD is BUSY; port=%p, d_id=%x, pd=%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port, page->aff_d_id, did_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = &((ns_resp_gpn_id_t *)ns_cmd->ns_data_buf)->pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gpn_id_t *)ns_cmd->ns_cmd_buf)->pid.port_id = page->aff_d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gpn_id_t *)ns_cmd->ns_cmd_buf)->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(ns_cmd->ns_data_buf, sizeof (la_wwn_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_ns_query(port, ns_cmd, job, 1, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "NS Query Response for D_ID page; rev=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " in_id=%x, cmdrsp=%x, reason=%x, expln=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_hdr.ct_rev, ns_cmd->ns_resp_hdr.ct_inid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_hdr.ct_cmdrsp, ns_cmd->ns_resp_hdr.ct_reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_hdr.ct_expln);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS || fctl_is_wwn_zero(pwwn) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * What this means is that the D_ID
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * disappeared from the Fabric.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (did_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(1, 0), "RSCN with D_ID page;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " NULL PD disappeared, rval=%x", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&did_pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr + (*listindex)++, did_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "RSCN: PD disappeared; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "d_id=%x, PWWN=%s", page->aff_d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GPN_ID for D_ID=%x failed", page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s disappeared from"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " fabric", page->aff_d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(3, 0), "RSCN with D_ID (%x) page; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PD disappeared, pd=%p", page->aff_d_id, did_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd = fctl_get_remote_port_by_pwwn(port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (did_pd != NULL && pwwn_pd != NULL && did_pd == pwwn_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is no change. Do PLOGI again and add it to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULP portmap baggage and return. Note: When RSCNs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arrive with per page states, the need for PLOGI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can be determined correctly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr + (*listindex)++, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pwwn_pd->pd_state == PORT_DEVICE_LOGGED_IN) ||
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (pwwn_pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pwwn_pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, page->aff_d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, sleep, pwwn_pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset LOGO tolerance to zero
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Also we are the PLOGI initiator now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_reset(&pwwn_pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_recepient = PD_PLOGI_INITIATOR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct fc_portmap *map =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr + *listindex - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
32f2f513dbd672742ea1b0e27bff6940a45fdb08Raghuram Prahlada FP_TRACE(FP_NHEAD1(1, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI succeeded: no skip(2)"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " for D_ID %x", page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_NO_SKIP_DEVICE_DISCOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, rval),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI to D_ID=%x failed", page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " disappeared from fabric",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page->aff_d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *listindex - 1, pwwn_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID (0x%x) page; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Case ONE, rval=%x, result=%x pd=%p", page->aff_d_id, rval,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (did_pd == NULL && pwwn_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *orp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *norp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Hunt down the orphan list before giving up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_orphan_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (orp = port->fp_orphan_list; orp; orp = norp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte norp = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&orp->orp_pwwn, pwwn) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->orp_next = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(orp ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd = fp_create_remote_port_by_ns(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page->aff_d_id, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pwwn_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&orp->orp_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " PWWN=%s reappeared in fabric",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page->aff_d_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(orp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*listindex)++, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID (0x%x) page; "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Case TWO", page->aff_d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pwwn_pd != NULL && did_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old_d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id = page->aff_d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * What this means is there is a new D_ID for this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port WWN. Take out the port device off D_ID
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list and put it back with a new D_ID. Perform
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI if already logged in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_d_id = pwwn_pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_changed_map(listptr + (*listindex)++, pwwn_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &d_id, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Case THREE, pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " state=%x", pwwn_pd, pwwn_pd->pd_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pwwn_pd->pd_state == PORT_DEVICE_LOGGED_IN) ||
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (pwwn_pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&pwwn_pd->pd_port_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s has a new"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " D_ID=%x now", old_d_id, ww_name, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, page->aff_d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, sleep, pwwn_pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *listindex - 1, pwwn_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pwwn_pd == NULL && did_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *ptr;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t len = 1;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed char old_ww_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(&did_pd->pd_port_name, old_ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * What this means is that there is a new Port WWN for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this D_ID; Mark the Port device as old and provide
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the new PWWN and D_ID combination as new.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr + (*listindex)++, did_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD2(9, 0),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_x Port with D_ID=%x, PWWN=%s has a new PWWN=%s now",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page->aff_d_id, old_ww_name, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ptr = listptr + (*listindex)++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_ns_getmap(port, job, &ptr, &len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page->aff_d_id - 1) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*listindex)--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A weird case of Port WWN and D_ID existence but not matching up
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * between them. Trust your instincts - Take the port device handle
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * off Port WWN list, fix it with new Port WWN and put it back, In
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the mean time mark the port device corresponding to the old port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN as OLD.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page; Case WEIRD, pwwn_pd=%p,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " did_pd=%p", pwwn_pd, did_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page; case WEIRD continued,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pwwn-d_id=%x pwwn-wwn=%x %x %x %x %x %x %x %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[2],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[5],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[6],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_pd->pd_port_name.raw_wwn[7]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pwwn_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr + (*listindex)++, pwwn_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, did_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (listptr + *listindex)->map_rscn_info.ulp_rscn_count =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(uintptr_t)job->job_cb_arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_changed_map(listptr + (*listindex)++, did_pd, NULL, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_pwwn_table(port, did_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_TRACE(FP_NHEAD1(6, 0), "RSCN with D_ID page; case WEIRD continued,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " d_id=%x, state=%x, did-wwn=%x %x %x %x %x %x %x %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_id.port_id, did_pd->pd_state,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[2],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[3],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[4],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[5],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[6],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_port_name.raw_wwn[7]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((did_pd->pd_state == PORT_DEVICE_LOGGED_IN) ||
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed (did_pd->pd_aux_flags & PD_LOGGED_OUT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fp_port_login(port, page->aff_d_id, job,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_CMD_PLOGI_RETAIN, sleep, did_pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *listindex - 1, did_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_fillout_old_map(listptr + *listindex - 1, did_pd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&did_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check with NS for the presence of this port WWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ns_validate_device(fc_local_port_t *port, fc_remote_port_t *pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job, int polled, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = FCTL_NS_VALIDATE_PD | ((polled) ? 0: FCTL_NS_ASYNC_REQUEST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t), sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)ns_cmd->ns_cmd_buf)->pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)ns_cmd->ns_data_buf)->pid.port_id = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_resp_gid_pn_t *)ns_cmd->ns_data_buf)->pid.priv_lilp_posit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fp_ns_query(port, ns_cmd, job, polled, sleep));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sanity check the LILP map returned by FCA
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_validate_lilp_map(fc_lilpmap_t *lilp_map)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lilp_map->lilp_length == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < lilp_map->lilp_length; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_is_valid_alpa(lilp_map->lilp_alpalist[count]) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Sanity check if the AL_PA is a valid address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_is_valid_alpa(uchar_t al_pa)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (fp_valid_alpas); count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (al_pa == fp_valid_alpas[count] || al_pa == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Post unsolicited callbacks to ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_ulp_unsol_cb(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_unsol_spec_t *ub_spec = (fp_unsol_spec_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_unsol_cb(ub_spec->port, ub_spec->buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ub_spec->buf->ub_frame.type);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ub_spec, sizeof (*ub_spec));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Perform message reporting in a consistent manner. Unless there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a strong reason NOT to use this function (which is very very rare)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all message reporting should go through this.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_printf(fc_local_port_t *port, int level, fp_mesg_dest_t dest, int fc_errno,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt, const char *fmt, ...)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_list ap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (level) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case CE_NOTE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_verbose & FP_WARNING_MESSAGES) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case CE_WARN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((port->fp_verbose & FP_FATAL_MESSAGES) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf = kmem_zalloc(256, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf, "fp(%d): ", port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_start(ap, fmt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) vsprintf(buf + strlen(buf), fmt, ap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_end(ap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *errmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_error(fc_errno, &errmsg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf + strlen(buf), " FC Error=%s", errmsg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t state, reason, action, expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fc_ulp_pkt_error(pkt, &state, &reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &action, &expln);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf + strlen(buf),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " state=%s, reason=%s", state, reason);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_resp_resid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(buf + strlen(buf),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " resp resid=%x\n", pkt->pkt_resp_resid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (dest) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FP_CONSOLE_ONLY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(level, "^%s", buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FP_LOG_ONLY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(level, "!%s", buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(level, "%s", buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(buf, 256);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fcio_login(fc_local_port_t *port, fcio_t *fcio, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed uint32_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd = NULL;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *held_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fcio->fcio_ibuf, &pwwn, sizeof (pwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = fctl_alloc_ns_cmd(sizeof (ns_req_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_resp_gid_pn_t), sizeof (ns_resp_gid_pn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NS_BUF_IS_USERLAND, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = NS_GID_PN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ns_req_gid_pn_t *)(ns_cmd->ns_cmd_buf))->pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_ns_query(port, ns_cmd, job, 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS || job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = BE_32(*((uint32_t *)ns_cmd->ns_data_buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte held_pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = held_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(held_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fp_create_remote_port_by_ns(port, d_id, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(held_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags &= ~JOB_TYPE_FP_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fp_port_login(port, d_id, job, FP_CMD_PLOGI_RETAIN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP, pd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(held_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (held_pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(held_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADDEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENODEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = kmem_zalloc(sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(changelist, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_type = PORT_DEVICE_USER_LOGIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist, 1, 1, KM_SLEEP, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_fcio_logout(fc_local_port_t *port, fcio_t *fcio, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *changelist;
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fcio->fcio_ibuf, &pwwn, sizeof (pwwn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_hold_remote_port_by_pwwn(port, &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_BADWWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_LOGINREQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_login_count >= 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags == PD_ELS_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_login_count > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_login_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = kmem_zalloc(sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(changelist, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_type = PORT_DEVICE_USER_LOGOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist, 1, 1, KM_SLEEP, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fp_alloc_pkt(port, sizeof (la_els_logo_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PORT_IDENTIFIER_LEN, KM_SLEEP, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_flags = FC_TRAN_INTR | pd->pd_login_class;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_pkt.pkt_tran_type = FC_PKT_EXCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_flags = FP_CMD_PLOGI_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_retry_count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_ulp_pkt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_logo_init(pd, cmd, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fp_sendcmd(port, cmd, port->fp_fca_handle) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_free_pkt(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fp_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fcio->fcio_errno = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist = kmem_zalloc(sizeof (*changelist), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(changelist, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_type = PORT_DEVICE_USER_LOGOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte changelist->map_state = PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_flags = PD_IDLE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fp_ulp_devc_cb(port, changelist, 1, 1, KM_SLEEP, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_release_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send a syslog event for adapter port level events.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_log_port_event(fc_local_port_t *port, char *subclass)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_t *attr_list;
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",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t)) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_log_sysevent(port->fp_port_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 FP_TRACE(FP_NHEAD1(9, 0), "Unable to send %s event", subclass);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_log_target_event(fc_local_port_t *port, char *subclass, la_wwn_t tgt_pwwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t port_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_t *attr_list;
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",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (la_wwn_t)) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_byte_array(attr_list, "target-port-wwn",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tgt_pwwn.raw_wwn, sizeof (la_wwn_t)) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nvlist_add_uint32(attr_list, "target-port-id",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_id) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_log_sysevent(port->fp_port_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 FP_TRACE(FP_NHEAD1(9, 0), "Unable to send %s event", subclass);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint32_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefp_map_remote_port_state(uint32_t rm_state)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (rm_state) {
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed case PORT_DEVICE_LOGGED_IN:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed return (FC_HBA_PORTSTATE_ONLINE);
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed case PORT_DEVICE_VALID:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed case PORT_DEVICE_INVALID:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed default:
3e5bc1d795e8c41f3680a71e3954e72d079ee46dReed return (FC_HBA_PORTSTATE_UNKNOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}