7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER START
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The contents of this file are subject to the terms of the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Common Development and Distribution License (the "License").
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * You may not use this file except in compliance with the License.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * or http://www.opensolaris.org/os/licensing.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * See the License for the specific language governing permissions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and limitations under the License.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * When distributing Covered Code, include this CDDL HEADER in each
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If applicable, add the following below this CDDL HEADER, with the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fields enclosed by brackets "[]" replaced with your own identifying
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * information: Portions Copyright [yyyy] [name of copyright owner]
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER END
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/conf.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/ddi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/stat.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/pci.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/sunddi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/modctl.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/file.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/cred.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/byteorder.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/atomic.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/scsi/scsi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/mac_client.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/modhash.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * leadville header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fibre-channel/fc.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fibre-channel/impl/fc_fcaif.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoe header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fcoe/fcoe_common.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <fcoei.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * forward declaration of stack functions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic uint32_t fcoei_xch_check(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_key_t key, mod_hash_val_t *val, void *arg);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_open(dev_t *devp, int flag, int otype, cred_t *credp);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_close(dev_t dev, int flag, int otype, cred_t *credp);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_ioctl(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_attach_init(fcoei_soft_state_t *ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int fcoei_detach_uninit(fcoei_soft_state_t *ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_watchdog(void *arg);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_events(fcoei_soft_state_t *ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_trigger_fp_attach(void *arg);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_abts_exchange(fcoei_exchange_t *xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_clear_watchdog_jobs(fcoei_soft_state_t *ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Driver identificaton stuff
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic struct cb_ops fcoei_cb_ops = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_open,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_close,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_ioctl,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nochpoll,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_prop_op,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang 0,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang D_MP | D_NEW | D_HOTPLUG,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang CB_REV,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang};
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic struct dev_ops fcoei_ops = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang DEVO_REV,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang 0,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nulldev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nulldev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_attach,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_detach,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nodev,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &fcoei_cb_ops,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_power,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_quiesce_not_needed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang};
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic struct modldrv modldrv = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &mod_driverops,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_NAME_VERSION,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &fcoei_ops,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang};
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic struct modlinkage modlinkage = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang MODREV_1,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &modldrv,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang NULL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang};
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Driver's global variables
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid *fcoei_state = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangint fcoei_use_ext_log = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Common loadable module entry points _init, _fini, _info
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangint
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang_init(void)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = ddi_soft_state_init(&fcoei_state, sizeof (fcoei_soft_state_t), 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "soft state init failed: %x", ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = mod_install(&modlinkage);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_soft_state_fini(&fcoei_state);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei mod_install failed: %x", ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Let FCTL initialize devo_bus_ops
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_init(&fcoei_ops);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei _init succeeded");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangint
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang_fini(void)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = mod_remove(&modlinkage);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_EXT_LOG(__FUNCTION__, "fcoei mod_remove failed: %x", ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_soft_state_fini(&fcoei_state);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei _fini succeeded");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangint
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang_info(struct modinfo *modinfop)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (mod_info(&modlinkage, modinfop));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Autoconfiguration entry points: attach, detach, getinfo
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int fcoe_ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int instance;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang instance = ddi_get_instance(dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "instance is %d", instance);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (cmd) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case DDI_ATTACH:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = ddi_soft_state_zalloc(fcoei_state, instance);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "ss zalloc failed: %x", ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Get the soft state, and do basic initialization with dip
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = ddi_get_soft_state(fcoei_state, instance);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_dip = dip;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_ret = fcoei_attach_init(ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fcoe_ret != FCOE_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_soft_state_free(fcoei_state, instance);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei_attach_init failed: "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "%x", fcoe_ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags |= SS_FLAG_TRIGGER_FP_ATTACH;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) timeout(fcoei_trigger_fp_attach, ss, FCOE_SEC2TICK(1));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei_attach succeeded: dip-%p, "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "cmd-%x", dip, cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case DDI_RESUME:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unsupported attach cmd-%X", cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int fcoe_ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int instance;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang instance = ddi_get_instance(dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = ddi_get_soft_state(fcoei_state, instance);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "get ss failed: dip-%p", dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (cmd) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case DDI_DETACH:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_flags & SS_FLAG_TRIGGER_FP_ATTACH) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "still await fp attach");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_flags & SS_FLAG_LV_BOUND) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fp is not detached yet");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_ret = fcoei_detach_uninit(ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fcoe_ret != FCOE_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei_detach_uninit failed:"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang " dip-%p, fcoe_ret-%d", dip, fcoe_ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "succeeded: dip-%p, cmd-%x", dip, cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case DDI_SUSPEND:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unspported detach cmd-%X", cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Device access entry points: open, close, ioctl
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_open(dev_t *devp, int flag, int otype, cred_t *credp)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (otype != OTYP_CHR) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "flag: %x", flag);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (EINVAL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (drv_priv(credp)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (EPERM);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * First of all, get related soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = ddi_get_soft_state(fcoei_state, (int)getminor(*devp));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ENXIO);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_ioctl_flags & FCOEI_IOCTL_FLAG_OPEN) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We don't support concurrent open
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (EBUSY);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_ioctl_flags |= FCOEI_IOCTL_FLAG_OPEN;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_close(dev_t dev, int flag, int otype, cred_t *credp)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (otype != OTYP_CHR) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "flag: %x, %p", flag, credp);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (EINVAL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * First of all, get related soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = ddi_get_soft_state(fcoei_state, (int)getminor(dev));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ENXIO);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(ss->ss_ioctl_flags & FCOEI_IOCTL_FLAG_OPEN)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If it's not open, we can exit
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ENODEV);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_ioctl_flags &= ~FCOEI_IOCTL_FLAG_OPEN;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cred_t *credp, int *rval)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int ret = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (drv_priv(credp) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "data: %p, %x", data, mode);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (EPERM);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Get related soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = ddi_get_soft_state(fcoei_state, (int32_t)getminor(dev));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!ss) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ENXIO);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Process ioctl
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (cmd) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "ioctl-0x%02X", cmd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = ENOTTY;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Set return value
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *rval = ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (ret);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_attach_init
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * init related stuff of the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ss = the soft state that will be processed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * if it succeeded or not
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic int
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_attach_init(fcoei_soft_state_t *ss)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_port_t *eport;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_client_t client_fcoei;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char taskq_name[32];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_els_logi_t *els = &ss->ss_els_logi;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang svc_param_t *class3_param;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Register fcoei to FCOE as its client
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_eport_flags = EPORT_FLAG_INI_MODE |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT_FLAG_IS_DIRECT_P2P;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_max_fc_frame_size = FCOE_MAX_FC_FRAME_SIZE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_private_frame_struct_size = sizeof (fcoei_frame_t);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ect_vectors(&client_fcoei);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_client_port_struct = ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_fcoe_ver = FCOE_VER_NOW;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "version: %x %x", FCOE_VER_NOW, fcoe_ver_now);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = ddi_prop_get_int(DDI_DEV_T_ANY, ss->ss_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "mac_id", -1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret == -1) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "get mac_id failed");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang client_fcoei.ect_channelid = ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's fcoe's responsiblity to initialize eport's all elements,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * so we needn't do eport initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport = fcoe_register_client(&client_fcoei);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (eport == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang goto fail_register_client;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_eport = eport;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_SET_DEFAULT_FPORT_ADDR(eport->eport_efh_dst);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Now it's time to register fca_tran to FCTL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Remember fc_local_port is transparent to FCA (fcoei)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_version = FCTL_FCA_MODREV_5;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_numports = 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_pkt_size = sizeof (fcoei_exchange_t);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_cmd_max = 2048;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * scsi_tran_hba_setup could need these stuff
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_dma_lim = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_iblock = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_dma_attr = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_fca_tran.fca_acc_attr = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Initialize vectors
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_fcatran_vectors(&ss->ss_fca_tran);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fc_fca_attach only sets driver's private, it has nothing to with
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * common port object between fcoei and leadville.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * After this attach, fp_attach will be triggered, and it will call
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fca_bind_port to let fcoei to know about common port object.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fc_fca_attach(ss->ss_dip, &ss->ss_fca_tran) != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang goto fail_fca_attach;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's time to do ss initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ret = ddi_create_minor_node(ss->ss_dip, "admin",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang S_IFCHR, ddi_get_instance(ss->ss_dip), DDI_NT_NEXUS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ret != DDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang goto fail_minor_node;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_port = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ss->ss_eport has been initialized
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_oxid_hash = mod_hash_create_idhash(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "fcoei_sol_oxid_hash", FCOEI_SOL_HASH_SIZE,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_null_valdtor);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_rxid_hash = mod_hash_create_idhash(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "fcoei_unsol_rxid_hash", FCOEI_UNSOL_HASH_SIZE,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_null_valdtor);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_create(&ss->ss_comp_xch_list, sizeof (fcoei_exchange_t),
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offsetof(fcoei_exchange_t, xch_comp_node));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_next_sol_oxid = 0xFFFF;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_next_unsol_rxid = 0xFFFF;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_init(&ss->ss_watchdog_mutex, 0, MUTEX_DRIVER, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cv_init(&ss->ss_watchdog_cv, NULL, CV_DRIVER, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) snprintf(taskq_name, 32, "leadville_fcoei_%d_taskq",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_get_instance(ss->ss_dip));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang taskq_name[31] = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_taskq = ddi_taskq_create(ss->ss_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang taskq_name, 64, TASKQ_DEFAULTPRI, DDI_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_link_state = FC_STATE_OFFLINE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_link_speed = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_port_event_counter = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_create(&ss->ss_event_list, sizeof (fcoei_event_t),
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offsetof(fcoei_event_t, ae_node));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_cnt1 = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_cnt2 = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_cnt = &ss->ss_sol_cnt1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_cnt1 = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_cnt2 = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_cnt = &ss->ss_unsol_cnt1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_ioctl_flags = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_init(&ss->ss_ioctl_mutex, 0, MUTEX_DRIVER, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(eport->eport_portwwn, els->nport_ww_name.raw_wwn, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(eport->eport_nodewwn, els->node_ww_name.raw_wwn, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.fcph_version = 0x2008;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.btob_credit = 3;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.cmn_features = 0x8800;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.conc_sequences = 0xff;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.relative_offset = 3;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els->common_service.e_d_tov = 0x07d0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang class3_param = (svc_param_t *)&els->class_3;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang class3_param->class_opt = 0x8800;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang class3_param->rcv_size = els->common_service.rx_bufsize = 2048;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang class3_param->conc_sequences = 0xff;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang class3_param->open_seq_per_xchng = 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Fill out RNID Management Information
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(ss->ss_eport->eport_portwwn, ss->ss_rnid.global_id, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_rnid.unit_type = FCOEI_RNID_HBA;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_rnid.ip_version = FCOEI_RNID_IPV4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Start our watchdog
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) ddi_taskq_dispatch(ss->ss_taskq,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_watchdog, ss, DDI_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (!(ss->ss_flags & SS_FLAG_WATCHDOG_RUNNING)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang delay(50);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Report the device to the system
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_report_dev(ss->ss_dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfail_minor_node:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fail_minor_node");
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) fc_fca_detach(ss->ss_dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfail_fca_attach:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_deregister_client(eport);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fail_fca_attach");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfail_register_client:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fail_register_client");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (DDI_FAILURE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_detach_uninit
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * uninit related stuff of the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ss = the soft state that will be processed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * if it succeeded or not
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangint
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_detach_uninit(fcoei_soft_state_t *ss)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Stop watchdog first
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_flags & SS_FLAG_WATCHDOG_RUNNING) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags |= SS_FLAG_TERMINATE_WATCHDOG;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cv_broadcast(&ss->ss_watchdog_cv);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Destroy the taskq
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_taskq_wait(ss->ss_taskq);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_taskq_destroy(ss->ss_taskq);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release all allocated resources
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_destroy(&ss->ss_ioctl_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_destroy(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cv_destroy(&ss->ss_watchdog_cv);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_destroy_idhash(ss->ss_sol_oxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_destroy_idhash(ss->ss_unsol_rxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_destroy(&ss->ss_event_list);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_eport->eport_deregister_client(ss->ss_eport);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_remove_minor_node(ss->ss_dip, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release itself
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_soft_state_free(fcoei_state, ddi_get_instance(ss->ss_dip));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (FCOE_SUCCESS);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_watchdog
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Perform periodic checking and routine tasks
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * arg = the soft state that will be processed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_watchdog(void *arg)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang clock_t tmp_delay;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang clock_t start_clock;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang clock_t last_clock;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * For debugging
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss = (fcoei_soft_state_t *)arg;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "ss %p", ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "sol_hash %p", ss->ss_sol_oxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unsol_hash %p", ss->ss_unsol_rxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags |= SS_FLAG_WATCHDOG_RUNNING;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang tmp_delay = FCOE_SEC2TICK(1) / 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang last_clock = CURRENT_CLOCK;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If nobody reqeusts to terminate the watchdog, we will work forever
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (!(ss->ss_flags & SS_FLAG_TERMINATE_WATCHDOG)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We handle all asynchronous events serially
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_events(ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * To avoid to check timing too freqently, we check
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * if we need skip timing stuff.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang start_clock = CURRENT_CLOCK;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((start_clock - last_clock) < tmp_delay) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang goto end_timing;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang last_clock = start_clock;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's time to do timeout checking of solicited exchanges
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_sol_cnt == (&ss->ss_sol_cnt1)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_sol_cnt2 == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_cnt = &ss->ss_sol_cnt2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_walk(ss->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_xch_check, ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_sol_cnt1 == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_sol_cnt = &ss->ss_sol_cnt1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_walk(ss->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_xch_check, ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's time to do timeout checking of unsolicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_unsol_cnt == (&ss->ss_unsol_cnt1)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_unsol_cnt2 == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_cnt = &ss->ss_unsol_cnt2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_walk(ss->ss_unsol_rxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_xch_check, ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_unsol_cnt1 == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_unsol_cnt = &ss->ss_unsol_cnt1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_walk(ss->ss_unsol_rxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_xch_check, ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Check if there are exchanges which are ready to complete
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_handle_comp_xch_list(ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang end_timing:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Wait for next cycle
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags |= SS_FLAG_WATCHDOG_IDLE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!list_is_empty(&ss->ss_event_list)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang goto skip_wait;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) cv_timedwait(&ss->ss_watchdog_cv,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &ss->ss_watchdog_mutex, CURRENT_CLOCK +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (clock_t)tmp_delay);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang skip_wait:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags &= ~SS_FLAG_WATCHDOG_IDLE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Do clear work before exit
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_clear_watchdog_jobs(ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Watchdog has stopped
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags &= ~SS_FLAG_WATCHDOG_RUNNING;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_clear_watchdog_jobs(fcoei_soft_state_t *ss)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_event_t *ae;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_frame_t *frm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (!list_is_empty(&ss->ss_event_list)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae = (fcoei_event_t *)list_head(&ss->ss_event_list);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_remove(&ss->ss_event_list, ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (ae->ae_type) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_SOL_FRAME:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm = (fcoe_frame_t *)ae->ae_obj;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_UNSOL_FRAME:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm = (fcoe_frame_t *)ae->ae_obj;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_free_netb(frm->frm_netb);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_PORT:
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&ss->ss_port_event_counter);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* FALLTHROUGH */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_RESET:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(ae, sizeof (fcoei_event_t));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_EXCHANGE:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* FALLTHROUGH */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_clear(ss->ss_unsol_rxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_clear(ss->ss_sol_oxid_hash);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (!list_is_empty(&ss->ss_comp_xch_list)) {
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) list_remove_head(&ss->ss_comp_xch_list);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_events
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Process the events one by one
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ss = the soft state that will be processed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_events(fcoei_soft_state_t *ss)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_event_t *ae = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's the only place to delete node from ss_event_list, so we needn't
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * hold mutex to check if the list is empty.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(!MUTEX_HELD(&ss->ss_watchdog_mutex));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (list_is_empty(&ss->ss_event_list) == B_FALSE) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae = (fcoei_event_t *)list_remove_head(&ss->ss_event_list);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&ss->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (ae->ae_type) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_SOL_FRAME:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_handle_sol_frame_done((fcoe_frame_t *)ae->ae_obj);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_UNSOL_FRAME:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_unsol_frame((fcoe_frame_t *)ae->ae_obj);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_EXCHANGE:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_event_exchange(ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_PORT:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_event_port(ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case AE_EVENT_RESET:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_event_reset(ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unsupported events");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_handle_tmout_xch_list
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete every exchange in the timed-out xch list of the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ss = the soft state that need be handled
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * When mod_hash_walk is in progress, we can't change the hashtable.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This is post-walk handling of exchange timing
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_handle_comp_xch_list(fcoei_soft_state_t *ss)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while ((xch = list_remove_head(&ss->ss_comp_xch_list)) != NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, xch->xch_fpkt->pkt_state,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_reason);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_xch_check
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Check if the exchange timed out or link is down
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * key = rxid of the unsolicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * val = the unsolicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * arg = the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * MH_WALK_CONTINUE = continue to walk
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We need send ABTS for timed-out for solicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If it's solicited FLOGI, we need set SS_FLAG_FLOGI_FAILED
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If the link is down, we think it has timed out too.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao/* ARGSUSED */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic uint32_t
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_xch_check(mod_hash_key_t key, mod_hash_val_t *val, void *arg)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = (fcoei_exchange_t *)val;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(xch->xch_ss == arg);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((xch->xch_end_tick < CURRENT_CLOCK) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (xch->xch_ss->ss_link_state != FC_STATE_OFFLINE)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (xch->xch_flags & XCH_FLAG_IN_SOL_HASH) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(xch->xch_oxid == CMHK(key));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's solicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_abts_exchange(xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (LA_ELS_FLOGI == ((ls_code_t *)(void *)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_cmd)->ls_code) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's solicited FLOGI
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_flags |= SS_FLAG_FLOGI_FAILED;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "oxid-%x/rxid-%x timed out",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_oxid, xch->xch_rxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_flags |= XCH_FLAG_TMOUT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_state = FC_PKT_TIMEOUT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_reason = FC_REASON_ABORTED;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&xch->xch_ss->ss_comp_xch_list, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (xch->xch_ss->ss_link_state == FC_STATE_OFFLINE) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "oxid-%x/rxid-%x offline complete",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_oxid, xch->xch_rxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_flags |= XCH_FLAG_TMOUT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_state = FC_PKT_PORT_OFFLINE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_reason = FC_REASON_OFFLINE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&xch->xch_ss->ss_comp_xch_list, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (MH_WALK_CONTINUE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_init_ifm
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * initialize fcoei_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = the frame that ifm need link to
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * xch = the exchange that ifm need link to
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * For solicited frames, it's called after FC frame header initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * For unsolicited frames, it's called just after the frame enters fcoei
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_init_ifm(fcoe_frame_t *frm, fcoei_exchange_t *xch)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_frm = frm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_xch = xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_rctl = FRM_R_CTL(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_trigger_fp_attach
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Trigger fp_attach for this fcoei port
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * arg = the soft state that fp will attach
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_trigger_fp_attach(void * arg)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss = (fcoei_soft_state_t *)arg;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang dev_info_t *child = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval = NDI_FAILURE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ndi_devi_alloc_sleep(ss->ss_dip, "fp", DEVI_PSEUDO_NODEID, &child);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (child == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't alloc dev_info");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fp/fctl need this property
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ddi_prop_update_string(DDI_DEV_T_NONE, child,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "bus-addr", "0,0") != DDI_PROP_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "update bus-addr failed");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) ndi_devi_free(child);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If it's physical HBA, fp.conf will register the property.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei is one software HBA, so we need register it manually
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ddi_prop_update_int(DDI_DEV_T_NONE, child,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "port", 0) != DDI_PROP_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "update port failed");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) ndi_devi_free(child);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It will call fp_attach eventually
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rval = ndi_devi_online(child, NDI_ONLINE_ATTACH);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_flags &= ~SS_FLAG_TRIGGER_FP_ATTACH;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (rval != NDI_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "devi_online: %d", rval);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "triggered successfully");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_abts_exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Send ABTS to abort solicited exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * xch = the exchange that will be aborted
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS frame uses the same oxid as the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_abts_exchange(fcoei_exchange_t *xch)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_packet_t *fpkt = xch->xch_fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_frame_t *frm = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * BLS_ABTS doesn't contain any other payload except FCFH
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm = xch->xch_ss->ss_eport->eport_alloc_frame(xch->xch_ss->ss_eport,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (frm == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't alloc frame: %p", xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_R_CTL(0x81, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_D_ID(fpkt->pkt_cmd_fhdr.d_id, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_S_ID(fpkt->pkt_cmd_fhdr.s_id, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_F_CTL(0x090000, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_SEQ_ID(0x01, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_OXID(xch->xch_oxid, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_RXID(xch->xch_rxid, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ifm(frm, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport->eport_tx_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_complete_xch
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * xch = the exchange that will be completed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = newly-allocated frame that has not been submitted
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * pkt_state = LV fpkt state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * pkt_reason = LV fpkt reason
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_complete_xch(fcoei_exchange_t *xch, fcoe_frame_t *frm,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t pkt_state, uint8_t pkt_reason)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_val_t val;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pkt_state != FC_PKT_SUCCESS) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "FHDR: %x/%x/%x, %x/%x/%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_cmd_fhdr.r_ctl,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_cmd_fhdr.f_ctl,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_cmd_fhdr.type,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_resp_fhdr.r_ctl,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_resp_fhdr.f_ctl,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_resp_fhdr.type);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "%p/%p/%x/%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch, frm, pkt_state, pkt_reason);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (frm != NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * It's newly-allocated frame , which we haven't sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport->eport_free_netb(frm->frm_netb);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "xch: %p, not submitted", xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If xch is in hash table, we need remove it
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (xch->xch_flags & XCH_FLAG_IN_SOL_HASH) {
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) mod_hash_remove(xch->xch_ss->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(xch->xch_oxid), &val);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT((fcoei_exchange_t *)val == xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_flags &= ~XCH_FLAG_IN_SOL_HASH;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (xch->xch_flags & XCH_FLAG_IN_UNSOL_HASH) {
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) mod_hash_remove(xch->xch_ss->ss_unsol_rxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(xch->xch_rxid), &val);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT((fcoei_exchange_t *)val == xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_flags &= ~XCH_FLAG_IN_UNSOL_HASH;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "xch not in any hash: %p", xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_state = pkt_state;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_reason = pkt_reason;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (xch->xch_fpkt->pkt_tran_flags & FC_TRAN_NO_INTR) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "polled xch is done: %p", xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sema_v(&xch->xch_sema);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_comp(xch->xch_fpkt);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}