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/*
1641617f6cce96286522a449e1412c6279a956c7Sriram Popuri * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore */
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore/*
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore */
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fibre channel Transport Library (fctl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function naming conventions:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Functions called from ULPs begin with fc_ulp_
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Functions called from FCAs begin with fc_fca_
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Internal functions begin with fctl_
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fibre channel packet layout:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * +---------------------+<--------+
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | ULP Packet private | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * +---------------------+ |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | |---------+
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | struct fc_packet |---------+
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * +---------------------+<--------+
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | FCA Packet private |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * | |
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * +---------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * So you loved the ascii art ? It's strongly desirable to cache
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocate the entire packet in one common place. So we define a set a
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * of rules. In a contiguous block of memory, the top portion of the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * block points to ulp packet private area, next follows the fc_packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * structure used extensively by all the consumers and what follows this
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * is the FCA packet private. Note that given a packet structure, it is
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * possible to get to the ULP and FCA Packet private fields using
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ulp_private and fca_private fields (which hold pointers) respectively.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It should be noted with a grain of salt that ULP Packet private size
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * varies between two different ULP types, So this poses a challenge to
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * compute the correct size of the whole block on a per port basis. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * transport layer doesn't have a problem in dealing with FCA packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * private sizes as it is the sole manager of ports underneath. Since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it's not a good idea to cache allocate different sizes of memory for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * different ULPs and have the ability to choose from one of these caches
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * based on ULP type during every packet allocation, the transport some
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * what wisely (?) hands off this job of cache allocation to the ULPs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * themselves.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * That means FCAs need to make their packet private size known to the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * transport to pass it up to the ULPs. This is done during
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_fca_attach(). And the transport passes this size up to ULPs during
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_port_attach() of each ULP.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This leaves us with another possible question; How are packets
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * allocated for ELS's started by the transport itself ? Well, the port
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * driver during attach time, cache allocates on a per port basis to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle ELSs too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/note.h>
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/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/poll.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.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/byteorder.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
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* These are referenced by fp.c! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint did_table_size = D_ID_HASH_TABLE_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint pwwn_table_size = PWWN_HASH_TABLE_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic fc_ulp_module_t *fctl_ulp_modules;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic fc_fca_port_t *fctl_fca_portlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_ulp_list_t *fctl_ulp_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char fctl_greeting[] =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fctl: %s ULP same type (0x%x) as existing module.\n";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *fctl_undefined = "Undefined";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This lock protects the fc_ulp_module_t linked list (i.e. mod_next field)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic krwlock_t fctl_ulp_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fctl_mod_ports_lock protects the mod_ports element in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_ports_t structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic krwlock_t fctl_mod_ports_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_port_lock protects the linked list of local port structures
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * (fctl_fca_portlist). When walking the list, this lock must be obtained
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * prior to any local port locks.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t fctl_port_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t fctl_ulp_list_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fctl_nwwn_list_t *fctl_nwwn_hash_table;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t fctl_nwwn_hash_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint fctl_nwwn_table_size = NWWN_HASH_TABLE_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(lint)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(MUTEX_PROTECTS_DATA(fctl_nwwn_hash_mutex, fctl_nwwn_hash_table))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(MUTEX_PROTECTS_DATA(fctl_ulp_list_mutex, fctl_ulp_list))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(RWLOCK_PROTECTS_DATA(fctl_ulp_lock, ulp_module::mod_next))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(RWLOCK_PROTECTS_DATA(fctl_mod_ports_lock, ulp_module::mod_ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_ports::port_handle))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(DATA_READABLE_WITHOUT_LOCK(ulp_module::mod_info))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_NOTE(MUTEX_PROTECTS_DATA(ulp_ports::port_mutex, ulp_ports::port_statec
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_ports::port_dstate))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#define FCTL_VERSION "20090729-1.70"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCTL_NAME_VERSION "SunFC Transport v" FCTL_VERSION
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *fctl_version = FCTL_NAME_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern struct mod_ops mod_miscops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlmisc modlmisc = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mod_miscops, /* type of module */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCTL_NAME_VERSION /* Module name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct modlinkage modlinkage = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODREV_1, (void *)&modlmisc, NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct bus_ops fctl_fca_busops = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte BUSO_REV,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nullbusmap, /* bus_map */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_get_intrspec */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_add_intrspec */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_remove_intrspec */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_ddi_map_fault, /* bus_map_fault */
cd21e7c548ae2a3b5e522244bf798f2a6b4ba02dGarrett D'Amore NULL, /* bus_dma_map */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_allochdl, /* bus_dma_allochdl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_freehdl, /* bus_dma_freehdl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_bindhdl, /* bus_dma_bindhdl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_unbindhdl, /* bus_unbindhdl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_flush, /* bus_dma_flush */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_win, /* bus_dma_win */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_dma_mctl, /* bus_dma_ctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fca_bus_ctl, /* bus_ctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_bus_prop_op, /* bus_prop_op */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_get_eventcookie */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_add_eventcall */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_remove_event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_post_event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_intr_ctl */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_config */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_unconfig */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_fm_init */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_fm_fini */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_fm_access_enter */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_fm_access_exit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, /* bus_power */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct kmem_cache *fctl_job_cache;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_errmap_t fc_errlist [] = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_FAILURE, "Operation failed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_SUCCESS, "Operation success" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_CAP_ERROR, "Capability error" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_CAP_FOUND, "Capability found" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_CAP_SETTABLE, "Capability settable" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_UNBOUND, "Port not bound" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_NOMEM, "No memory" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADPACKET, "Bad packet" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_OFFLINE, "Port offline" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_OLDPORT, "Old Port" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_NO_MAP, "No map available" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_TRANSPORT_ERROR, "Transport error" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ELS_FREJECT, "ELS Frejected" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ELS_PREJECT, "ELS PRejected" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ELS_BAD, "Bad ELS request" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ELS_MALFORMED, "Malformed ELS request" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_TOOMANY, "Too many commands" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_UB_BADTOKEN, "Bad Unsolicited buffer token" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_UB_ERROR, "Unsolicited buffer error" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_UB_BUSY, "Unsolicited buffer busy" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADULP, "Bad ULP" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADTYPE, "Bad Type" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_UNCLAIMED, "Not Claimed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ULP_SAMEMODULE, "Same ULP Module" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ULP_SAMETYPE, "Same ULP Type" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ABORTED, "Command Aborted" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ABORT_FAILED, "Abort Failed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADEXCHANGE, "Bad Exchange" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADWWN, "Bad World Wide Name" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADDEV, "Bad Device" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADCMD, "Bad Command" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADOBJECT, "Bad Object" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_BADPORT, "Bad Port" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_NOTTHISPORT, "Not on this Port" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_PREJECT, "Operation Prejected" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_FREJECT, "Operation Frejected" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_PBUSY, "Operation Pbusyed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_FBUSY, "Operation Fbusyed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_ALREADY, "Already done" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_LOGINREQ, "PLOGI Required" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_RESETFAIL, "Reset operation failed" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_INVALID_REQUEST, "Invalid Request" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_OUTOFBOUNDS, "Out of Bounds" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_TRAN_BUSY, "Command transport Busy" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_STATEC_BUSY, "State change Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_DEVICE_BUSY, "Port driver is working on this device" }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t remote_stop_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ABTS, "Abort Sequence" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ABTX, "Abort Exchange" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t general_reasons [] = {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_REASON_HW_ERROR, "Hardware Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_SEQ_TIMEOUT, "Sequence Timeout" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ABORTED, "Aborted" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ABORT_FAILED, "Abort Failed" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_NO_CONNECTION, "No Connection" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_XCHG_DROPPED, "Exchange Dropped" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ILLEGAL_FRAME, "Illegal Frame" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ILLEGAL_LENGTH, "Illegal Length" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_UNSUPPORTED, "Unsuported" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_RX_BUF_TIMEOUT, "Receive Buffer Timeout" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FCAL_OPN_FAIL, "FC AL Open Failed" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_OVERRUN, "Over run" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_QFULL, "Queue Full" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ILLEGAL_REQ, "Illegal Request", },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_PKT_BUSY, "Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_OFFLINE, "Offline" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_BAD_XID, "Bad Exchange Id" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_XCHG_BSY, "Exchange Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_NOMEM, "No Memory" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_BAD_SID, "Bad S_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_NO_SEQ_INIT, "No Sequence Initiative" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_DIAG_BUSY, "Diagnostic Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_DMA_ERROR, "DMA Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_CRC_ERROR, "CRC Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ABORT_TIMEOUT, "Abort Timeout" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FCA_UNIQUE, "FCA Unique" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t rjt_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_D_ID, "Invalid D_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_S_ID, "Invalid S_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_TEMP_UNAVAILABLE, "Temporarily Unavailable" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_PERM_UNAVAILABLE, "Permamnently Unavailable" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_CLASS_NOT_SUPP, "Class Not Supported", },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_DELIMTER_USAGE_ERROR,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "Delimeter Usage Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_TYPE_NOT_SUPP, "Type Not Supported" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_LINK_CTRL, "Invalid Link Control" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_R_CTL, "Invalid R_CTL" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_F_CTL, "Invalid F_CTL" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_OX_ID, "Invalid OX_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_RX_ID, "Invalid RX_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_SEQ_ID, "Invalid Sequence ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_DF_CTL, "Invalid DF_CTL" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_SEQ_CNT, "Invalid Sequence count" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_PARAM, "Invalid Parameter" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_EXCH_ERROR, "Exchange Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_PROTOCOL_ERROR, "Protocol Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INCORRECT_LENGTH, "Incorrect Length" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_UNEXPECTED_ACK, "Unexpected Ack" },
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang { FC_REASON_UNEXPECTED_LR, "Unexpected Link reset" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_LOGIN_REQUIRED, "Login Required" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_EXCESSIVE_SEQS, "Excessive Sequences"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang " Attempted" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_EXCH_UNABLE, "Exchange incapable" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_ESH_NOT_SUPP, "Expiration Security Header "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "Not Supported" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_NO_FABRIC_PATH, "No Fabric Path" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_VENDOR_UNIQUE, "Vendor Unique" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t n_port_busy_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_PHYSICAL_BUSY, "Physical Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_N_PORT_RESOURCE_BSY, "Resource Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_N_PORT_VENDOR_UNIQUE, "Vendor Unique" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t f_busy_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FABRIC_BSY, "Fabric Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_N_PORT_BSY, "N_Port Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t ls_ba_rjt_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID_LA_CODE, "Invalid Link Application Code" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_LOGICAL_ERROR, "Logical Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_LOGICAL_BSY, "Logical Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_PROTOCOL_ERROR_RJT, "Protocol Error Reject" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_CMD_UNABLE, "Unable to Perform Command" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_CMD_UNSUPPORTED, "Unsupported Command" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_VU_RJT, "Vendor Unique" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_reason_t fs_rjt_reasons [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_INVALID_CMD, "Invalid Command" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_INVALID_VER, "Invalid Version" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_LOGICAL_ERR, "Logical Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_INVALID_IUSIZE, "Invalid IU Size" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_LOGICAL_BUSY, "Logical Busy" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_PROTOCOL_ERR, "Protocol Error" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_CMD_UNABLE, "Unable to Perform Command" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_CMD_UNSUPPORTED, "Unsupported Command" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_FS_VENDOR_UNIQUE, "Vendor Unique" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_action_t n_port_busy_actions [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_ACTION_SEQ_TERM_RETRY, "Retry terminated Sequence" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_ACTION_SEQ_ACTIVE_RETRY, "Retry Active Sequence" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_action_t rjt_timeout_actions [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_ACTION_RETRYABLE, "Retryable" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_ACTION_NON_RETRYABLE, "Non Retryable" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_REASON_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_expln_t ba_rjt_explns [] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_EXPLN_NONE, "No Explanation" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_EXPLN_INVALID_OX_RX_ID, "Invalid X_ID" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_EXPLN_SEQ_ABORTED, "Sequence Aborted" },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_EXPLN_INVALID, NULL }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_pkt_error_t fc_pkt_errlist[] = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_SUCCESS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Operation Success",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { FC_PKT_REMOTE_STOP,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "Remote Stop",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang remote_stop_reasons,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_LOCAL_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Local Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_timeout_actions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_NPORT_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_Port Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_timeout_actions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_FABRIC_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Fabric Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_timeout_actions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_LOCAL_BSY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Local Busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TRAN_BSY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Transport Busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_NPORT_BSY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "N_Port Busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n_port_busy_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n_port_busy_actions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_FABRIC_BSY,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Fabric Busy",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte f_busy_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_LS_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Link Service Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_ba_rjt_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_BA_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Basic Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ls_ba_rjt_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ba_rjt_explns,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TIMEOUT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Timeout",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rjt_timeout_actions,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_FS_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Fabric Switch Reject",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fs_rjt_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_TRAN_ERROR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Packet Transport error",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_FAILURE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Packet Failure",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte general_reasons,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_PORT_OFFLINE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Port Offline",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_PKT_ELS_IN_PROGRESS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ELS is in Progress",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_init()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&fctl_ulp_lock, NULL, RW_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&fctl_mod_ports_lock, NULL, RW_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fctl_port_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&fctl_nwwn_hash_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_hash_table = kmem_zalloc(sizeof (*fctl_nwwn_hash_table) *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_table_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_modules = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fca_portlist = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_job_cache = kmem_cache_create("fctl_cache",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (job_request_t), 8, fctl_cache_constructor,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_cache_destructor, NULL, NULL, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_job_cache == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fctl_nwwn_hash_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*fctl_nwwn_hash_table) * fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = mod_install(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fctl_job_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fctl_nwwn_hash_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*fctl_nwwn_hash_table) * fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The mod_uninstall code doesn't call _fini when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there is living dependent module on fctl. So
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * there is no need to be extra careful here ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_fini()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = mod_remove(&modlinkage)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_destroy(fctl_job_cache);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(fctl_nwwn_hash_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*fctl_nwwn_hash_table) * fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_info(struct modinfo *modinfo_p)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (mod_info(&modlinkage, modinfo_p));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_cache_constructor(void *buf, void *cdarg, int kmflag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job = (job_request_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&job->job_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_init(&job->job_fctl_sema, 0, NULL, SEMA_DEFAULT, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_init(&job->job_port_sema, 0, NULL, SEMA_DEFAULT, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_cache_destructor(void *buf, void *cdarg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job = (job_request_t *)buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_destroy(&job->job_fctl_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_destroy(&job->job_port_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&job->job_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_add:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add a ULP module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Codes:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_ULP_SAMEMODULE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fc_ulp_add prints a warning message if there is already a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * similar ULP type attached and this is unlikely to change as
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * we trudge along. Further, this function returns a failure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code if the same module attempts to add more than once for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the same FC-4 type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_add(fc_ulp_modinfo_t *ulp_info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_module_t *mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_module_t *prev;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_list_t *new;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *fca_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ntry = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ulp_info != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure ulp_rev matches fctl version.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Whenever non-private data structure or non-static interface changes,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should use an increased FCTL_ULP_MODREV_# number here and in all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ulps to prevent version mismatch.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_info->ulp_rev != FCTL_ULP_MODREV_4) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fctl: ULP %s version mismatch;"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ULP %s would not be loaded", ulp_info->ulp_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_info->ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADULP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = kmem_zalloc(sizeof (*new), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(new != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->ulp_info = ulp_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_ulp_list != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->ulp_next = fctl_ulp_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_list = new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (rw_tryenter(&fctl_ulp_lock, RW_WRITER) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte delay(drv_usectohz(1000000));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ntry++ > FC_ULP_ADD_RETRY_COUNT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_list_t *list;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_list_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (last = NULL, list = fctl_ulp_list; list != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = list->ulp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->ulp_info == ulp_info) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->ulp_next = list->ulp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_list = list->ulp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(list, sizeof (*list));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fctl: ULP %s unable to load",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_info->ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules, prev = NULL; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mod->mod_info != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_info == mod->mod_info &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_info->ulp_type == mod->mod_info->ulp_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_ULP_SAMEMODULE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_info->ulp_type == mod->mod_info->ulp_type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, fctl_greeting, ulp_info->ulp_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_info->ulp_type);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod = kmem_zalloc(sizeof (*mod), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info = ulp_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->mod_next = mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_modules = mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Schedule a job to each port's job_handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread to attach their ports with this ULP.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_ATTACH_ULP, JOB_TYPE_FCTL_ASYNC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(fca_port->port_handle, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_remove
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove a ULP module
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A misbehaving ULP may call this routine while I/Os are in progress.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Currently there is no mechanism to detect it to fail such a request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Codes:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_remove(fc_ulp_modinfo_t *ulp_info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_module_t *mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_list_t *list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_list_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_module_t *prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (last = NULL, list = fctl_ulp_list; list != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = list->ulp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->ulp_info == ulp_info) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->ulp_next = list->ulp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_list = list->ulp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(list, sizeof (*list));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules, prev = NULL; mod != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mod->mod_info == ulp_info) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mod) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->mod_next = mod->mod_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ulp_modules = mod->mod_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((next = mod->mod_ports) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_ports = next->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_ulp_port(next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(mod, sizeof (*mod));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The callers typically cache allocate the packet, complete the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DMA setup for pkt_cmd and pkt_resp fields of the packet and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * call this function to see if the FCA is interested in doing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * its own intialization. For example, socal may like to initialize
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the soc_hdr which is pointed to by the pkt_fca_private field
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and sitting right below fc_packet_t in memory.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The caller is required to ensure that pkt_pd is populated with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle that it was given when the transport notified it about the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * device this packet is associated with. If there is no associated
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * device, pkt_pd must be set to NULL. A non-NULL pkt_pd will cause an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * increment of the reference count for said pd. When the packet is freed,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reference count will be decremented. This reference count, in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * combination with the PD_GIVEN_TO_ULPS flag guarantees that the pd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will not wink out of existence while there is a packet outstanding.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function and fca_init_pkt must not perform any operations that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * would result in a call back to the ULP, as the ULP may be required
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to hold a mutex across this call to ensure that the pd in question
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * won't go away prior the call to fc_ulp_transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULPs are responsible for using the handles they are given during state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * change callback processing in a manner that ensures consistency. That
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is, they must be aware that they could be processing a state change
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * notification that tells them the device associated with a particular
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle has gone away at the same time they are being asked to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initialize a packet using that handle. ULPs must therefore ensure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that their state change processing and packet initialization code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * paths are sufficiently synchronized to avoid the use of an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * invalidated handle in any fc_packet_t struct that is passed to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_ulp_init_packet() function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_init_packet(opaque_t port_handle, fc_packet_t *pkt, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Call the FCA driver's fca_init_pkt entry point function. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_init_pkt(port->fp_fca_handle, pkt, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval == FC_SUCCESS) && (pd != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A !NULL pd here must still be a valid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reference to the fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is called before destroying the cache allocated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_packet to free up (and uninitialize) any resource specially
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocated by the FCA driver during tran_init_pkt().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the pkt_pd field in the given fc_packet_t struct is not NULL, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the pd_ref_count reference count is decremented for the indicated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_uninit_packet(opaque_t port_handle, fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pkt != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Call the FCA driver's fca_un_init_pkt entry point function */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_un_init_pkt(port->fp_fca_handle, pkt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval == FC_SUCCESS) && (pd != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If at this point the state of this fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct is PORT_DEVICE_INVALID, it probably means somebody
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is cleaning up old (e.g. retried) packets. If the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd_ref_count has also dropped to zero, it's time to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * deallocate this fc_remote_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state == PORT_DEVICE_INVALID &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Also deallocate the associated fc_remote_node_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct if it has no other associated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fctl_destroy_remote_port(port, pd) == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (node != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_getportmap(opaque_t port_handle, fc_portmap_t **map, uint32_t *len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int job_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *tmp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t tmp_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *change_list = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
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 mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_dev_count && (port->fp_dev_count ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_total_devices)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fillout_map(port, &change_list, &listlen, 1, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen > *len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_map = (fc_portmap_t *)kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen * sizeof (fc_portmap_t), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_map == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*map) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(*map, (*len) * sizeof (fc_portmap_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *map = tmp_map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (change_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(change_list, *map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen * sizeof (fc_portmap_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(change_list, listlen * sizeof (fc_portmap_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (flag) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_PLOGI_DONTCARE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_code = JOB_PORT_GETMAP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_PLOGI_PRESERVE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_code = JOB_PORT_GETMAP_PLOGI_ALL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_INVALID_REQUEST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Submit a job request to the job handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread to get the map and wait
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(job_code, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (opaque_t)map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_arg = (opaque_t)len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The result of the last I/O operation is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in job_code. We don't care to look at it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Rather we look at the number of devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that are found to fill out the map for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we're here, we're returning a map to the caller, which means
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we'd better make sure every pd in that map has the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PD_GIVEN_TO_ULPS flag set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_len = *len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_map = *map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmp_len-- != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_map->map_state != PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_remote_port_t *)tmp_map->map_pd;
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 tmp_map++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_login(opaque_t port_handle, fc_packet_t **ulp_pkt, uint32_t listlen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t **tmp_array;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang job_request_t *job;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_rscn_info_t *rscnp =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_ulp_rscn_info_t *)(ulp_pkt[0])->pkt_ulp_rscn_infop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is OFFLINE, or if the port driver is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * being SUSPENDED/PM_SUSPENDED/DETACHED, block all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI operations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
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 (port->fp_soft_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (FP_SOFT_IN_DETACH | FP_SOFT_SUSPEND | FP_SOFT_POWER_DOWN))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the rscn count in the packet is not the same as the rscn count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_local_port_t, then one or more new RSCNs has occurred.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rscnp != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != FC_INVALID_RSCN_COUNT) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != port->fp_rscn_count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_DEVICE_BUSY_NEW_RSCN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_array = kmem_zalloc(sizeof (*tmp_array) * listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < listlen; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_array[count] = ulp_pkt[count];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_flags = ((ulp_pkt[0]->pkt_tran_flags) & FC_TRAN_NO_INTR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ? 0 : JOB_TYPE_FCTL_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int polled;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte polled = ((ulp_pkt[0]->pkt_tran_flags) &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_TRAN_NO_INTR) ? 0 : JOB_TYPE_FCTL_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < listlen; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = ((ulp_pkt[count]->pkt_tran_flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte & FC_TRAN_NO_INTR) ? 0 : JOB_TYPE_FCTL_ASYNC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(next == polled);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_PLOGI_GROUP, job_flags, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts = tmp_array;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_listlen = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (listlen--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_packet_t *pkt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt = tmp_array[listlen];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pkt->pkt_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd->pd_flags == PD_ELS_IN_PROGRESS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_pd->pd_flags == PD_ELS_MARK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set the packet state and let the port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * driver call the completion routine
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from its thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pkt->pkt_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_ELS_IN_PROGRESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_pd->pd_state == PORT_DEVICE_INVALID ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pkt->pkt_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_LOCAL_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pkt->pkt_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(job_flags & JOB_TYPE_FCTL_ASYNC)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteopaque_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_remote_port(opaque_t port_handle, la_wwn_t *pwwn, int *error,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int create)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A ULP now knows about this pd, so mark it
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 return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology) && create) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_NS_CMD, 0, NULL, NULL, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
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 if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_NOMEM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
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 job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = ((ns_resp_gid_pn_t *)ns_cmd->ns_data_buf)->pid.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
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 KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
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 job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_jobwait(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_result != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the port device is created now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A ULP now knows about this pd, so mark it
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 } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a NS object exists in the host and query is performed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on that object, we should retrieve it from our basket
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and return it right here, there by saving a request going
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * all the up to the Name Server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_port_ns(opaque_t port_handle, opaque_t pd, fc_ns_cmd_t *ns_req)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fabric;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fabric = FC_IS_TOP_SWITCH(port->fp_topology) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Name server query can't be performed for devices not in Fabric
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fabric && pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADOBJECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_CMD_A_REG(ns_req->ns_cmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = fctl_update_host_ns_values(port, ns_req);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Guess what, FC-GS-2 currently prohibits (not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the strongest language though) setting of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NS object values by other ports. But we might
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get that changed to at least accommodate setting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * symbolic node/port names - But if disks/tapes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * were going to provide a method to set these
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * values directly (which in turn might register
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with the NS when they come up; yep, for that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to happen the disks will have to be very well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * behaved Fabric citizen) we won't need to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * register the symbolic port/node names for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other ports too (rather send down SCSI commands
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the devices to set the names)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Be that as it may, let's continue to fail
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * registration requests for other ports. period.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADOBJECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fabric) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (!fabric) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_retrieve_host_ns_values(port, ns_req));
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, 0, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ns_cmd != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_code = ns_req->ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ns_req->ns_req_payload, ns_cmd->ns_cmd_buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_req->ns_req_len);
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 (ns_req->ns_resp_len >= ns_cmd->ns_data_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ns_cmd->ns_data_buf, ns_req->ns_resp_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&ns_cmd->ns_resp_hdr, &ns_req->ns_resp_hdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_ct_header_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_free_ns_cmd(ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_transport(opaque_t port_handle, fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd, *newpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_rscn_info_t *rscnp =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_ulp_rscn_info_t *)pkt->pkt_ulp_rscn_infop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_tran_flags & FC_TRAN_DUMPING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_transport(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, pkt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_STATEC_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A locus of race conditions */
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 mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the rscn count in the packet is not the same as the rscn count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_local_port_t, then one or more new RSCNs has occurred.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rscnp != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != FC_INVALID_RSCN_COUNT) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != port->fp_rscn_count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_DEVICE_BUSY_NEW_RSCN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pkt->pkt_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newpd = fctl_get_remote_port_by_pwwn_mutex_held(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pd->pd_port_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The remote port (pd) in the packet is no longer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * usable, as the old pd still exists we can use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN to check if we have a current pd for the device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we want. Either way we continue with the old logic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * whether we have a new pd or not, as the new pd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * could be bad, or have become unusable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((newpd) && (newpd != pd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There is a better remote port (pd) to try,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we need to fix the reference counts, etc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&newpd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newpd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_pd = newpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&newpd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_state == PORT_DEVICE_INVALID) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_ref_count == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will create another PD hole
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * where we have a reference to a pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but someone else could remove it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fctl_destroy_remote_port(port, pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte == 0) && (node != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = newpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = (pd->pd_state == PORT_DEVICE_VALID) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGINREQ : FC_BADDEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags != PD_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_DEVICE_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADDEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (FC_IS_REAL_DEVICE(pkt->pkt_cmd_fhdr.d_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADPACKET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_transport(port->fp_fca_handle, pkt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_issue_els(opaque_t port_handle, fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_rscn_info_t *rscnp =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fc_ulp_rscn_info_t *)pkt->pkt_ulp_rscn_infop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the port is OFFLINE, or if the port driver is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * being SUSPENDED/PM_SUSPENDED/DETACHED, block all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ELS operations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
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 mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_STATEC_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the rscn count in the packet is not the same as the rscn count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_local_port_t, then one or more new RSCNs has occurred.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rscnp != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != FC_INVALID_RSCN_COUNT) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (rscnp->ulp_rscn_count != port->fp_rscn_count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_DEVICE_BUSY_NEW_RSCN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = pkt->pkt_pd) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_state != PORT_DEVICE_LOGGED_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = (pd->pd_state == PORT_DEVICE_VALID) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGINREQ : FC_BADDEV;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_flags != PD_IDLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_DEVICE_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_BADDEV);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_els_send(port->fp_fca_handle, pkt));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_uballoc(opaque_t port_handle, uint32_t *count, uint32_t size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t type, uint64_t *tokens)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_ub_alloc(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tokens, size, count, type));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_ubfree(opaque_t port_handle, uint32_t count, uint64_t *tokens)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_ub_free(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count, tokens));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_ubrelease(opaque_t port_handle, uint32_t count, uint64_t *tokens)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_ub_release(port->fp_fca_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count, tokens));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_abort(opaque_t port_handle, fc_packet_t *pkt, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_abort(port->fp_fca_handle, pkt, flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Submit an asynchronous request to the job handler if the sleep
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flag is set to KM_NOSLEEP, as such calls could have been made
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in interrupt contexts, and the goal is to avoid busy waiting,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blocking on a conditional variable, a semaphore or any of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * synchronization primitives. A noticeable draw back with this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * asynchronous request is that an FC_SUCCESS is returned long
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * before the reset is complete (successful or not).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_linkreset(opaque_t port_handle, la_wwn_t *pwwn, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Many a times, this function is called from interrupt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * contexts and there have been several dead locks and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hangs - One of the simplest work arounds is to fib
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if a RESET is in progress.
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 return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ward off this reset if a state change is in progress.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_STATEC_BUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_soft_state |= FP_SOFT_IN_LINK_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_busy_port(port) != 0) {
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 return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sleep == KM_SLEEP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_LINK_RESET, 0, NULL, NULL, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
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 fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = job->job_result;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = fctl_alloc_job(JOB_LINK_RESET, JOB_TYPE_FCTL_ASYNC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_link_reset_done, port, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job == NULL) {
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 fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_NOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = (void *)pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_priority_enque_job(port, job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_port_reset(opaque_t port_handle, uint32_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_PORT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_LINK_RESET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_ADAPTER:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_RESET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_CORE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_RESET_CRASH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_reset(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_fca_handle, FC_FCA_RESET_CORE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_port_login_params(opaque_t port_handle, la_els_logi_t *login_params)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Copy the login parameters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *login_params = port->fp_service_params;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_port_instance(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteopaque_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_port_handle(int port_instance)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t port_handle = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *cur;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cur = fctl_fca_portlist; cur; cur = cur->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cur->port_handle->fp_instance == port_instance) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_handle = (opaque_t)cur->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_error(int fc_errno, char **errmsg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_error(fc_errno, errmsg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_pkt_error(fc_packet_t *pkt, char **state, char **reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **action, char **expln)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_pkt_error(pkt, state, reason, action, expln));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an ULP by the specified name exists, return FC_SUCCESS, else FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_is_name_present(caddr_t ulp_name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_list_t *list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (list = fctl_ulp_list; list != NULL; list = list->ulp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(list->ulp_info->ulp_name, ulp_name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_ulp_list_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return port WWN for a port Identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_pwwn_by_did(opaque_t port_handle, fc_portid_t d_id, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_did(port, d_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return a port map for a port WWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_pwwn_to_portmap(opaque_t port_handle, la_wwn_t *bytes, fc_portmap_t *map)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn(port, bytes);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_did = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_hard_addr = pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_type = pd->pd_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(map->map_type <= PORT_DEVICE_DELETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pd->pd_fc4types, map->map_fc4_types, sizeof (pd->pd_fc4types));
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 map->map_nwwn = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteopaque_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_fca_device(opaque_t port_handle, fc_portid_t d_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_fca_tran->fca_get_device == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->fp_fca_tran->fca_get_device(port->fp_fca_handle, d_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_port_notify(opaque_t port_handle, uint32_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_fca_tran->fca_notify) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NOTIFY_TARGET_MODE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options |= FP_TARGET_MODE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_NOTIFY_NO_TARGET_MODE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_options &= ~FP_TARGET_MODE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = port->fp_fca_tran->fca_notify(port->fp_fca_handle, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_disable_relogin(opaque_t *fc_port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_get_remote_port_by_pwwn((fc_local_port_t *)fc_port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_DISABLE_RELOGIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_enable_relogin(opaque_t *fc_port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_get_remote_port_by_pwwn((fc_local_port_t *)fc_port, pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_DISABLE_RELOGIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_fca_init
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Overload the FCA bus_ops vector in its dev_ops with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_fca_busops to handle all the INITchilds for "sf"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in one common place.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should be called from FCA _init routine.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_init(struct dev_ops *fca_devops_p)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_devops_p->devo_bus_ops = &fctl_fca_busops;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __lock_lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_fca_attach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_attach(dev_info_t *fca_dip, fc_fca_tran_t *tran)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When we are in a position to offer downward compatibility
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should change the following check to allow lower revision
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of FCAs; But we aren't there right now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tran->fca_version != FCTL_FCA_MODREV_5) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *name = ddi_driver_name(fca_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(name != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fctl: FCA %s version mismatch"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " please upgrade %s", name, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_driver_private(fca_dip, (caddr_t)tran);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_fca_detach
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_detach(dev_info_t *fca_dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_driver_private(fca_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the frame is a Link response Frame; Handle all cases (P_RJT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * F_RJT, P_BSY, F_BSY fall into this category). Check also for some Basic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Link Service responses such as BA_RJT and Extended Link Service response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * such as LS_RJT. If the response is a Link_Data Frame or something that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function doesn't understand return FC_FAILURE; Otherwise, fill out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * various fields (state, action, reason, expln) from the response gotten
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the packet and return FC_SUCCESS.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_update_errors(fc_packet_t *pkt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (pkt->pkt_resp_fhdr.r_ctl) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_P_RJT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t prjt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prjt = pkt->pkt_resp_fhdr.ro;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_NPORT_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_action = (prjt & 0xFF000000) >> 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = (prjt & 0xFF0000) >> 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_F_RJT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t frjt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frjt = pkt->pkt_resp_fhdr.ro;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_FABRIC_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_action = (frjt & 0xFF000000) >> 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = (frjt & 0xFF0000) >> 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_P_BSY: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t pbsy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pbsy = pkt->pkt_resp_fhdr.ro;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_NPORT_BSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_action = (pbsy & 0xFF000000) >> 24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = (pbsy & 0xFF0000) >> 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_F_BSY_LC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_F_BSY_DF: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t fbsy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fbsy = pkt->pkt_resp_fhdr.type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_FABRIC_BSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = (fbsy & 0xF0) >> 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_LS_BA_RJT: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t brjt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte brjt = *(uint32_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_BA_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = (brjt & 0xFF0000) >> 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_expln = (brjt & 0xFF00) >> 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_ELS_RSP: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_els_rjt_t *lsrjt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lsrjt = (la_els_rjt_t *)pkt->pkt_resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lsrjt->ls_code.ls_code == LA_ELS_RJT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_state = FC_PKT_LS_RJT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_reason = lsrjt->reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pkt->pkt_action = lsrjt->action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_error(int fc_errno, char **errmsg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_error(fc_errno, errmsg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_pkt_error(fc_packet_t *pkt, char **state, char **reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **action, char **expln)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_pkt_error(pkt, state, reason, action, expln));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * WWN to string goodie. Unpredictable results will happen
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if enough memory isn't supplied in str argument. If you
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are wondering how much does this routine need, it is just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (2 * WWN size + 1). So for a WWN size of 8 bytes the str
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * argument should have atleast 17 bytes allocated.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_wwn_to_str(la_wwn_t *wwn, caddr_t str)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < FCTL_WWN_SIZE(wwn); count++, str += 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(str, "%02x", wwn->raw_wwn[count]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *str = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#define FC_ATOB(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : \
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ((x) >= 'a' && (x) <= 'f') ? \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((x) - 'a' + 10) : ((x) - 'A' + 10))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_str_to_wwn(caddr_t str, la_wwn_t *wwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uchar_t byte;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (*str) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte byte = FC_ATOB(*str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte str++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte byte = byte << 4 | FC_ATOB(*str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte str++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn->raw_wwn[count++] = byte;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCA driver's intercepted bus control operations.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_fca_bus_ctl(dev_info_t *fca_dip, dev_info_t *rip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ddi_ctl_enum_t op, void *arg, void *result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (op) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_CTLOPS_REPORTDEV:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_CTLOPS_IOMIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_CTLOPS_INITCHILD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_initchild(fca_dip, (dev_info_t *)arg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case DDI_CTLOPS_UNINITCHILD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_uninitchild(fca_dip, (dev_info_t *)arg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ddi_ctlops(fca_dip, rip, op, arg, result));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FCAs indicate the maximum number of ports supported in their
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tran structure. Fail the INITCHILD if the child port number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is any greater than the maximum number of ports supported
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by the FCA.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_initchild(dev_info_t *fca_dip, dev_info_t *port_dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int port_no;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int port_len;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char name[20];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_tran_t *tran;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_info_t *dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portprop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port_len = sizeof (port_no);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* physical port do not has this property */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portprop = ddi_prop_get_int(DDI_DEV_T_ANY, port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "phyport-instance", -1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((portprop == -1) && ndi_dev_is_persistent_node(port_dip)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clear any addr bindings created by fcode interpreter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in devi_last_addr so that a ndi_devi_find should never
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return this fcode node.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_name_addr(port_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_prop_op(DDI_DEV_T_ANY, port_dip, PROP_LEN_AND_VAL_BUF,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "port",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (caddr_t)&port_no, &port_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tran = (fc_fca_tran_t *)ddi_get_driver_private(fca_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tran != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf((char *)name, "%x,0", port_no);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_name_addr(port_dip, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dip = ndi_devi_find(fca_dip, ddi_binding_name(port_dip), name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Even though we never initialize FCode nodes of fp, such a node
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * could still be there after a DR operation. There will only be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one FCode node, so if this is the one, clear it and issue a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ndi_devi_find again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((portprop == -1) && dip && ndi_dev_is_persistent_node(dip)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_name_addr(dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dip = ndi_devi_find(fca_dip, ddi_binding_name(port_dip), name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((portprop == -1) && dip && (dip != port_dip)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Here we have a duplicate .conf entry. Clear the addr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set previously and return failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_name_addr(port_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_uninitchild(dev_info_t *fca_dip, dev_info_t *port_dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_set_name_addr(port_dip, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DDI_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic dev_info_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_findchild(dev_info_t *pdip, char *cname, char *caddr)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_info_t *dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cname != NULL && caddr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ASSERT(DEVI_BUSY_OWNED(pdip)); */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (dip = ddi_get_child(pdip); dip != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dip = ddi_get_next_sibling(dip)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (strcmp(cname, ddi_node_name(dip)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((addr = ddi_get_name_addr(dip)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "bus-addr", &addr) == DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(caddr, addr) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_free(addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_prop_free(addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (strcmp(caddr, addr) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (dip);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_check_npiv_portindex(dev_info_t *dip, int vindex)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fc_local_port_t *)fc_ulp_get_port_handle(instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((!port) || (vindex <= 0) || (vindex >= FC_NPIV_MAX_PORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i = vindex-1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_npiv_portindex[i] == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (vindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_npiv_portindex(dev_info_t *dip)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fc_local_port_t *)fc_ulp_get_port_handle(instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < FC_NPIV_MAX_PORT; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_npiv_portindex[i] == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (i+1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_set_npiv_portindex(dev_info_t *dip, int index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int instance;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte instance = ddi_get_instance(dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fc_local_port_t *)fc_ulp_get_port_handle(instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_npiv_portindex[index - 1] = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_fca_create_npivport(dev_info_t *parent,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_info_t *phydip, char *nname, char *pname, uint32_t *vindex)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0, devstrlen;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char *devname, *cname, *caddr, *devstr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_info_t *child = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*vindex == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portnum = fctl_get_npiv_portindex(phydip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *vindex = portnum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portnum = fctl_check_npiv_portindex(phydip, *vindex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (portnum == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Cann't find valid port index, fail to create devnode");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NDI_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devname = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(devname, "fp@%x,0", portnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devstrlen = strlen(devname) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte devstr = i_ddi_strdup(devname, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_ddi_parse_name(devstr, &cname, &caddr, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_findchild(parent, cname, caddr) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ndi_devi_alloc_sleep(parent, cname, DEVI_PSEUDO_NODEID, &child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (child == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fctl_create_npiv_port fail to create new devinfo");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "bus-addr", caddr) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fctl%d: prop update bus-addr %s@%s failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(parent), cname, caddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ndi_devi_free(child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strlen(nname) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "node-name", nname) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ndi_devi_free(child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strlen(pname) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port-name", pname) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ndi_devi_free(child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_update_int(DDI_DEV_T_NONE, child,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port", portnum) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp%d: prop_update port %s@%s failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(parent), cname, caddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ndi_devi_free(child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_update_int(DDI_DEV_T_NONE, child,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "phyport-instance", ddi_get_instance(phydip)) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fp%d: prop_update phyport-instance %s@%s failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(parent), cname, caddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ndi_devi_free(child);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ndi_devi_online(child, NDI_ONLINE_ATTACH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != NDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fp%d: online_driver %s failed",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_instance(parent), cname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = NDI_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto freememory;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_set_npiv_portindex(phydip, portnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefreememory:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(devstr, devstrlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(devname, MAXNAMELEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_add_port(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_t *new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = kmem_zalloc(sizeof (*new), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->port_handle = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->port_next = fctl_fca_portlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fca_portlist = new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_remove_port(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *prev;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_get_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((ulp_port->port_dstate & ULP_PORT_ATTACH) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __lock_lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_remove_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = fctl_fca_portlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (list != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->port_handle == port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_fca_portlist = list->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->port_next = list->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(list, sizeof (*list));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = list->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_attach_ulps(fc_local_port_t *port, fc_attach_cmd_t cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct modlinkage *linkage)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t state;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_port_info_t info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_linkage = linkage;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_dip = port->fp_port_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_handle = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_dma_behavior = port->fp_dma_behavior;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_fcp_dma = port->fp_fcp_dma;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_acc_attr = port->fp_fca_tran->fca_acc_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_fca_pkt_size = port->fp_fca_tran->fca_pkt_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_reset_action = port->fp_reset_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It is still possible that another thread could have gotten
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * into the detach process before we got here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_IN_DETACH) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_statec_busy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_state = port->fp_bind_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_state = port->fp_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (state = FC_PORT_STATE_MASK(info.port_state)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_LOOP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_NAMESERVICE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_state &= ~state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_state |= FC_STATE_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((info.port_state & FC_STATE_LOOP) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_flags = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_pwwn = port->fp_service_params.nport_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_nwwn = port->fp_service_params.node_ww_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((port->fp_soft_state & FP_SOFT_FCA_IS_NODMA) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (mod->mod_info->ulp_type == FC_TYPE_IS8802_SNAP)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We don't support IP over FC on FCOE HBA
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ulp_port = fctl_get_ulp_port(mod, port)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_add_ulp_port(mod, port, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ulp_port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ulp_port->port_statec = ((info.port_state &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_STATE_ONLINE) ? FC_ULP_STATEC_ONLINE :
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_ULP_STATEC_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_downgrade(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((port->fp_soft_state & FP_SOFT_FCA_IS_NODMA) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (mod->mod_info->ulp_type == FC_TYPE_IS8802_SNAP)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We don't support IP over FC on FCOE HBA
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_get_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ulp_port != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_pre_attach(ulp_port, cmd) == FC_FAILURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_init_dma_attr(port, mod, &info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = mod->mod_info->ulp_port_attach(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle, &info, cmd, s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_post_attach(mod, ulp_port, cmd, rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS && cmd == FC_CMD_ATTACH &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(mod->mod_info->ulp_name, "fcp") == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ddi_get_driver_private(info.port_dip) != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_pre_attach(fc_ulp_ports_t *ulp_port, fc_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port->port_dstate & ULP_PORT_ATTACH) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((ulp_port->port_dstate & ULP_PORT_POWER_DOWN) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ulp_port->port_dstate & ULP_PORT_ATTACH) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(ulp_port->port_dstate & ULP_PORT_SUSPEND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_UP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ulp_port->port_dstate & ULP_PORT_ATTACH) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(ulp_port->port_dstate & ULP_PORT_POWER_DOWN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate |= ULP_PORT_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_post_attach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_attach_cmd_t cmd, int rval)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int be_chatty;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd == FC_CMD_ATTACH || cmd == FC_CMD_RESUME ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd == FC_CMD_POWER_UP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate &= ~ULP_PORT_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte be_chatty = (rval == FC_FAILURE_SILENT) ? 0 : 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = ulp_port->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "attach";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "resume";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_UP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "power up";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (be_chatty) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fctl(%d): %s failed for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance, op, mod->mod_info->ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_ATTACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate |= ULP_PORT_ATTACH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_RESUME:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate &= ~ULP_PORT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_UP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate &= ~ULP_PORT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_detach_ulps(fc_local_port_t *port, fc_detach_cmd_t cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct modlinkage *linkage)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_port_info_t info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_linkage = linkage;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_dip = port->fp_port_dip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_handle = (opaque_t)port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_acc_attr = port->fp_fca_tran->fca_acc_attr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte info.port_fca_pkt_size = port->fp_fca_tran->fca_pkt_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ulp_port = fctl_get_ulp_port(mod, port)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_pre_detach(ulp_port, cmd) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_init_dma_attr(port, mod, &info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = mod->mod_info->ulp_port_detach(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle, &info, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_post_detach(mod, ulp_port, cmd, rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd == FC_CMD_DETACH && strcmp(mod->mod_info->ulp_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcp") == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ddi_get_driver_private(info.port_dip) == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_statec = FC_ULP_STATEC_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_init_dma_attr(fc_local_port_t *port, fc_ulp_module_t *mod,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_port_info_t *info)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((strcmp(mod->mod_info->ulp_name, "fcp") == 0) ||
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (strcmp(mod->mod_info->ulp_name, "ltct") == 0)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_cmd_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcp_cmd_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_data_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcp_data_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_resp_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcp_rsp_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (strcmp(mod->mod_info->ulp_name, "fcsm") == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_cmd_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcsm_cmd_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_data_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_resp_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcsm_rsp_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (strcmp(mod->mod_info->ulp_name, "fcip") == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_cmd_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcip_cmd_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_data_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_resp_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_fcip_rsp_attr;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_cmd_dma_attr = info->port_data_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang info->port_resp_dma_attr =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang port->fp_fca_tran->fca_dma_attr; /* default */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_pre_detach(fc_ulp_ports_t *ulp_port, fc_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ulp_port->port_dstate & ULP_PORT_ATTACH) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ulp_port->port_dstate & ULP_PORT_ATTACH) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate & ULP_PORT_SUSPEND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_DOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ulp_port->port_dstate & ULP_PORT_ATTACH) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate & ULP_PORT_POWER_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate |= ULP_PORT_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_post_detach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_detach_cmd_t cmd, int rval)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd == FC_CMD_DETACH || cmd == FC_CMD_SUSPEND ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd == FC_CMD_POWER_DOWN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate &= ~ULP_PORT_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = ulp_port->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "detach";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "suspend";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_DOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = "power down";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fctl(%d): %s failed for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance, op, mod->mod_info->ulp_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_DETACH:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate &= ~ULP_PORT_ATTACH;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_SUSPEND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate |= ULP_PORT_SUSPEND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_CMD_POWER_DOWN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_dstate |= ULP_PORT_POWER_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_ulp_ports_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_add_ulp_port(fc_ulp_module_t *ulp_module, fc_local_port_t *port_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_READ_HELD(&fctl_ulp_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_WRITE_HELD(&fctl_mod_ports_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = ulp_module->mod_ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = next->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = fctl_alloc_ulp_port(sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (new);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->port_handle = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_module->mod_ports = new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->port_next = new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (new);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_ulp_ports_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_alloc_ulp_port(int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new = kmem_zalloc(sizeof (*new), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (new);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&new->port_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (new);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_remove_ulp_port(struct ulp_module *ulp_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_WRITE_HELD(&fctl_ulp_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_WRITE_HELD(&fctl_mod_ports_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = ulp_module->mod_ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next->port_handle == port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next->port_dstate & ULP_PORT_ATTACH) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = next->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((next->port_dstate & ULP_PORT_ATTACH) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_module->mod_ports = next->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->port_next = next->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_ulp_port(next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_dealloc_ulp_port(fc_ulp_ports_t *next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&next->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(next, sizeof (*next));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic fc_ulp_ports_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_ulp_port(struct ulp_module *ulp_module, fc_local_port_t *port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_LOCK_HELD(&fctl_ulp_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(RW_LOCK_HELD(&fctl_mod_ports_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (next = ulp_module->mod_ports; next != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = next->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next->port_handle == port_handle) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pass state change notfications on to registered ULPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Can issue wakeups to client callers who might be waiting for completions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on other threads.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Caution: will silently deallocate any fc_remote_port_t and/or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t structs it finds that are not in use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_ulp_statec_cb(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t s_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t new_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_port_clist_t *clist = (fc_port_clist_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(clist != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = clist->clist_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s_id = port->fp_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (clist->clist_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = FC_ULP_STATEC_ONLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_STATE_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = FC_ULP_STATEC_OFFLINE_TIMEOUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = FC_ULP_STATEC_OFFLINE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = FC_ULP_STATEC_DONT_CARE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
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) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang 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 if (clist->clist_map[count].map_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_wwn_t pwwn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_portid_t d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = clist->clist_map[count].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) {
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,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pwwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd != clist->clist_map[count].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 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].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check for duplicate map entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd1, *pd2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(clist->clist_map != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < clist->clist_len-1; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd1 = clist->clist_map[count].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd1 == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count2 = count+1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count2 < clist->clist_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count2++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd2 = clist->clist_map[count2].map_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd2 == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd1 == pd2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map[count].map_flags |=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_DUPLICATE_MAP_ENTRY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_get_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FCTL_DISALLOW_CALLBACKS(ulp_port->port_dstate)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ulp_port->port_statec) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_STATEC_DONT_CARE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port->port_statec != new_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_statec = new_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_STATEC_ONLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_STATEC_OFFLINE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port->port_statec == new_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_statec = new_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_ULP_STATEC_OFFLINE_TIMEOUT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port->port_statec == new_state ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state == FC_ULP_STATEC_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port->port_statec = new_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_statec_callback(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle, (opaque_t)port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_state, clist->clist_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_map, clist->clist_len, s_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
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
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = clist->clist_map[count].map_pd) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_map[count].map_state !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_GIVEN_TO_ULPS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This fc_remote_port_t is no longer referenced
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by any ULPs. Deallocate it if its pd_ref_count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has reached zero.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fctl_destroy_remote_port(port, pd) == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (node != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(clist->clist_map,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*(clist->clist_map)) * clist->clist_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (clist->clist_wait) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clist->clist_wait = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&clist->clist_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&clist->clist_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(clist, sizeof (*clist));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate an fc_remote_node_t struct to represent a remote node for the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * given nwwn. This will also add the nwwn to the global nwwn table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the newly-allocated struct. Returns NULL if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the kmem_zalloc fails or if the enlist_wwn attempt fails.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_node_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_create_remote_node(la_wwn_t *nwwn, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rnodep = kmem_zalloc(sizeof (*rnodep), sleep)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&rnodep->fd_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_node_name = *nwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_flags = FC_REMOTE_NODE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_numports = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_enlist_nwwn_table(rnodep, sleep) != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnodep, sizeof (*rnodep));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deconstruct and free the given fc_remote_node_t struct (remote node struct).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Silently skips the deconstruct/free if there are any fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (remote port device) structs still referenced by the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_destroy_remote_node(fc_remote_node_t *rnodep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Look at the count and linked list of of remote ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (fc_remote_port_t structs); bail if these indicate that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given fc_remote_node_t may be in use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep->fd_numports != 0 || rnodep->fd_portlistp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rnodep, sizeof (*rnodep));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the given fc_remote_node_t to the global fctl_nwwn_hash_table[]. This
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uses the nwwn in the fd_node_name.raw_wwn of the given struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This only fails if the kmem_zalloc fails. This does not check for a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unique or pre-existing nwwn in the fctl_nwwn_hash_table[].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is only called from fctl_create_remote_node().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_enlist_nwwn_table(fc_remote_node_t *rnodep, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_elem_t *new;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_list_t *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&rnodep->fd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((new = kmem_zalloc(sizeof (*new), sleep)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->fne_nodep = rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_is_wwn_zero(&rnodep->fd_node_name) == FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(rnodep->fd_node_name.raw_wwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &fctl_nwwn_hash_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link it in at the head of the hash list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new->fne_nextp = head->fnl_headp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->fnl_headp = new;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the given fc_remote_node_t from the global fctl_nwwn_hash_table[].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This uses the nwwn in the fd_node_name.raw_wwn of the given struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_delist_nwwn_table(fc_remote_node_t *rnodep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_list_t *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_elem_t *elem;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_elem_t *prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&fctl_nwwn_hash_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&rnodep->fd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(rnodep->fd_node_name.raw_wwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &fctl_nwwn_hash_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = head->fnl_headp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (elem != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (elem->fne_nodep == rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Found it -- unlink it from the list & decrement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the count for the hash chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->fnl_headp = elem->fne_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->fne_nextp = elem->fne_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = elem->fne_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (elem != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(elem, sizeof (*elem));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a reference to an fc_remote_node_t struct for the given node_wwn.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the global fctl_nwwn_hash_table[]. Identical to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_lock_remote_node_by_nwwn() function, except that this does NOT increment
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_count reference count in the f_device_t before returning.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is called by: fctl_create_remote_port_t().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OLD COMMENT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: The calling thread needs to make sure it isn't holding any device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mutex (more so the fc_remote_node_t that could potentially have this wwn).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_node_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_remote_node_by_nwwn(la_wwn_t *node_wwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_elem_t *elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *next;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_node_t *rnodep = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(node_wwn->raw_wwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(index >= 0 && index < fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = fctl_nwwn_hash_table[index].fnl_headp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (elem != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = elem->fne_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(node_wwn, &next->fd_node_name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = elem->fne_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a reference to an fc_remote_node_t struct for the given node_wwn.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the global fctl_nwwn_hash_table[]. Increments the fd_numports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reference count in the f_device_t before returning.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is only called by fctl_create_remote_port_t().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_node_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_lock_remote_node_by_nwwn(la_wwn_t *node_wwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_nwwn_elem_t *elem;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *next;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_node_t *rnodep = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(node_wwn->raw_wwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(index >= 0 && index < fctl_nwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = fctl_nwwn_hash_table[index].fnl_headp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (elem != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next = elem->fne_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(node_wwn, &next->fd_node_name) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_numports++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&next->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elem = elem->fne_nextp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate and initialize an fc_remote_port_t struct & returns a pointer to
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the newly allocated struct. Only fails if the kmem_zalloc() fails.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_alloc_remote_port(fc_local_port_t *port, la_wwn_t *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id, uchar_t recepient, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(FC_IS_REAL_DEVICE(d_id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = kmem_zalloc(sizeof (*pd), sleep)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_constructor(&pd->pd_logo_tc, FC_LOGO_TOLERANCE_LIMIT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FC_LOGO_TOLERANCE_TIME_LIMIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&pd->pd_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_name = *port_wwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_recepient = recepient;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deconstruct and free the given fc_remote_port_t struct (unconditionally).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_dealloc_remote_port(fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_tc_destructor(&pd->pd_logo_tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(pd, sizeof (*pd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the given fc_remote_port_t onto the linked list of remote port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices associated with the given fc_remote_node_t. Does NOT add the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t to the list if already exists on the list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_link_remote_port_to_remote_node(fc_remote_node_t *rnodep,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ports = rnodep->fd_portlistp; ports != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ports = ports->pd_port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ports == pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The given fc_remote_port_t is already on the linked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list chain for the given remote node, so bail now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Add the fc_remote_port_t to the tail of the linked list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->pd_port_next = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_portlistp = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Link the fc_remote_port_t back to the associated fc_remote_node_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_remote_nodep = rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the specified fc_remote_port_t from the linked list of remote ports
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the given fc_remote_node_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a count of the _remaining_ fc_remote_port_t structs on the linked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list of the fc_remote_node_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fd_numports on the given fc_remote_node_t is decremented, and if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it hits zero then this function also removes the fc_remote_node_t from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * global fctl_nwwn_hash_table[]. This appears to be the ONLY WAY that entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are removed from the fctl_nwwn_hash_table[].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_unlink_remote_port_from_remote_node(fc_remote_node_t *rnodep,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rcount = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *last;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&rnodep->fd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Go thru the linked list of fc_remote_port_t structs for the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t; try to find the specified fc_remote_port_t (pd).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ports = rnodep->fd_portlistp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (ports != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ports == pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* Found the requested fc_remote_port_t */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = ports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ports = ports->pd_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ports) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcount = --rnodep->fd_numports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rcount == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Note: this is only ever called from here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_nwwn_table(rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->pd_port_next = pd->pd_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep->fd_portlistp = pd->pd_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_remote_nodep = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_nwwn_hash_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rcount);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the given fc_remote_port_t struct to the d_id table in the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_local_port_t struct. Hashes based upon the pd->pd_port_id.port_id in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No memory allocs are required, so this never fails, but it does use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (pd->pd_aux_flags & PD_IN_DID_QUEUE) to keep duplicates off the list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (There does not seem to be a way to tell the caller that a duplicate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * exists.)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_enlist_did_table(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct d_id_hash *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_aux_flags & PD_IN_DID_QUEUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_did_table[D_ID_HASH_FUNC(pd->pd_port_id.port_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte did_table_size)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct d_id_hash *tmp_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search down in each bucket for a duplicate pd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Also search for duplicate D_IDs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This DEBUG code will force an ASSERT if a duplicate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is ever found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < did_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_head = &port->fp_did_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = tmp_head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmp_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tmp_pd != pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd->pd_state != PORT_DEVICE_INVALID &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd->pd_type != PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tmp_pd->pd_port_id.port_id !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = tmp_pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(pd->pd_d_stack, sizeof (pd->pd_d_stack));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_d_depth = getpcstack(pd->pd_d_stack, FC_STACK_DEPTH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_did_hnext = head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->d_id_head = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_IN_DID_QUEUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->d_id_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the given fc_remote_port_t struct from the d_id table in the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_local_port_t struct. Hashes based upon the pd->pd_port_id.port_id in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Does nothing if the requested fc_remote_port_t was not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_delist_did_table(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d_id;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct d_id_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd_next;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_did_table[D_ID_HASH_FUNC(d_id, did_table_size)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_next = head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd_next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == pd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* Found the given fc_remote_port_t */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = pd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_next = pd_next->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Found the given fc_remote_port_t; now remove it from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * d_id list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->d_id_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->d_id_head = pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->pd_did_hnext = pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_IN_DID_QUEUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_did_hnext = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the given fc_remote_port_t struct to the pwwn table in the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_local_port_t struct. Hashes based upon the pd->pd_port_name.raw_wwn
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No memory allocs are required, so this never fails.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_enlist_pwwn_table(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_is_wwn_zero(&pd->pd_port_name) == FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(pd->pd_port_name.raw_wwn),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *tmp_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *tmp_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search down in each bucket for a duplicate pd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search also for a duplicate WWN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Throw an ASSERT if any duplicate is found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = tmp_head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmp_pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tmp_pd != pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_pd->pd_state != PORT_DEVICE_INVALID &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd->pd_type != PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fctl_wwn_cmp(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &tmp_pd->pd_port_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pd->pd_port_name) != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_pd = tmp_pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(pd->pd_w_stack, sizeof (pd->pd_w_stack));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_w_depth = getpcstack(pd->pd_w_stack, FC_STACK_DEPTH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_wwn_hnext = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_head = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure we tie fp_dev_count to the size of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pwwn_table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the given fc_remote_port_t struct from the pwwn table in the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_local_port_t struct. Hashes based upon the pd->pd_port_name.raw_wwn
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Does nothing if the requested fc_remote_port_t was not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_delist_pwwn_table(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd_next;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *last;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(pwwn.raw_wwn), pwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_next = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd_next != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd_next == pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* Found the given fc_remote_port_t */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last = pd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd_next = pd_next->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Found the given fc_remote_port_t; now remove it from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pwwn list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure we tie fp_dev_count to the size of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pwwn_table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_head = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last->pd_wwn_hnext = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_wwn_hnext = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the d_id table of the specified fc_local_port_t for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t that matches the given d_id. Hashes based upon
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the given d_id.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a pointer to the fc_remote_port_t struct, but does not update any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reference counts or otherwise indicate that the fc_remote_port_t is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_remote_port_by_did(fc_local_port_t *port, uint32_t d_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct d_id_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_did_table[D_ID_HASH_FUNC(d_id, did_table_size)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_port_id.port_id == d_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Match found -- break out of the loop */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint /* uncomment when there is a consumer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_hold_remote_port(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the d_id table of the specified fc_local_port_t for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t that matches the given d_id. Hashes based upon
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the given d_id. Returns a pointer to the fc_remote_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Increments pd_ref_count in the fc_remote_port_t if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t is found at the given d_id.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fc_remote_port_t is ignored (treated as non-existent) if either
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * its pd_state == PORT_DEVICE_INVALID _OR_ its pd_type == PORT_DEVICE_OLD.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_hold_remote_port_by_did(fc_local_port_t *port, uint32_t d_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct d_id_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_did_table[D_ID_HASH_FUNC(d_id, did_table_size)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_port_id.port_id == d_id && pd->pd_state !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID && pd->pd_type != PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __lock_lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the pwwn table of the specified fc_local_port_t for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t that matches the given pwwn. Hashes based upon the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given pwwn->raw_wwn. Returns a pointer to the fc_remote_port_t struct,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but does not update any reference counts or otherwise indicate that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_remote_port_t is in use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_remote_port_by_pwwn(fc_local_port_t *port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(pwwn->raw_wwn), pwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&pd->pd_port_name, pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Basically the same as fctl_get_remote_port_by_pwwn(), but requires that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the caller already hold the fp_mutex in the fc_local_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_remote_port_by_pwwn_mutex_held(fc_local_port_t *port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(pwwn->raw_wwn), pwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&pd->pd_port_name, pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks in the pwwn table of the specified fc_local_port_t for the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t that matches the given d_id. Hashes based upon the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given pwwn->raw_wwn. Returns a pointer to the fc_remote_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Increments pd_ref_count in the fc_remote_port_t if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t is found at the given pwwn.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fc_remote_port_t is ignored (treated as non-existent) if either
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * its pd_state == PORT_DEVICE_INVALID _OR_ its pd_type == PORT_DEVICE_OLD.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_hold_remote_port_by_pwwn(fc_local_port_t *port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = HASH_FUNC(WWN_HASH_KEY(pwwn->raw_wwn), pwwn_table_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&pd->pd_port_name, pwwn) == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state != PORT_DEVICE_INVALID &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type != PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count >= 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Unconditionally decrement pd_ref_count in the given fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If pd_ref_count reaches zero, then this function will see if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t has been marked for deallocation. If so (and also if there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are no other potential operations in progress, as indicated by the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PD_ELS_IN_PROGRESS & PD_ELS_MARK settings in the pd_flags), then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_destroy_remote_port_t() is called to deconstruct/free the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t (which will also remove it from the d_id and pwwn tables
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * on the associated fc_local_port_t). If the associated fc_remote_node_t is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * longer in use, then it too is deconstructed/freed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_release_remote_port(fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int remove = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_node_t *node;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = pd->pd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_ref_count > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_ref_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_ref_count == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_aux_flags & PD_NEEDS_REMOVAL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_flags != PD_ELS_IN_PROGRESS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_flags != PD_ELS_MARK)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte remove = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_NEEDS_REMOVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(node != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (remove) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fc_remote_port_t struct has to go away now, so call the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cleanup function to get it off the various lists and remove
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * references to it in any other associated structs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_destroy_remote_port(port, pd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No more fc_remote_port_t references found in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * associated fc_remote_node_t, so deallocate the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t (if it even exists).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_fillout_map(fc_local_port_t *port, fc_portmap_t **map, uint32_t *len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int whole_map, int justcopy, int orphan)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int full_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t topology;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *old_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *last_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_portmap_t *listptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte topology = port->fp_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orphan) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!FC_IS_TOP_SWITCH(topology));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (full_list = listlen = index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 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 full_list++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type != PORT_DEVICE_NOCHANGE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listlen++;
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 (whole_map == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listlen == 0 && *len == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *map = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (full_list == 0 && *len == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *map = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = full_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*len == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(*map == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (whole_map == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = *map = kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*listptr) * listlen, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = listlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = *map = kmem_zalloc(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (*listptr) * full_list, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = full_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * By design this routine mandates the callers to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ask for a whole map when they specify the length
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and the listptr.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(whole_map == 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*len < full_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = full_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr = *map;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *len = full_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < pwwn_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_pwwn_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((whole_map == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type == PORT_DEVICE_NOCHANGE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state == PORT_DEVICE_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(listptr, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (justcopy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_state != PORT_DEVICE_INVALID);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_state = pd->pd_state =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_DEVICE_INVALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove this from the PWWN hash table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = old_pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(old_pd == head->pwwn_head);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_head = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd->pd_wwn_hnext = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure we tie fp_dev_count to the size
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the pwwn_table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_pd->pd_wwn_hnext = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_topology == FC_TOP_PRIVATE_LOOP &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_statec_busy && !orphan) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_check_alpa_list(port, old_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove if the port device has stealthily
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * present in the D_ID hash table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, old_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(old_pd->pd_remote_nodep != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator = (old_pd->pd_recepient ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&old_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orphan) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_print_if_not_orphan(port, old_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan(port, old_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(topology) && initiator) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan(port, old_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortejob_request_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_alloc_job(int job_code, int job_flags, void (*comp) (opaque_t, uchar_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opaque_t arg, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = (job_request_t *)kmem_cache_alloc(fctl_job_cache, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_result = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_code = job_code;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_flags = job_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_cb_arg = arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_comp = comp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_private = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_pkts = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_ulp_listlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef __lock_lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_counter = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __lock_lint */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_dealloc_job(job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_cache_free(fctl_job_cache, (void *)job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_enque_job(fc_local_port_t *port, job_request_t *job)
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_job_tail == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_job_head == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_head = port->fp_job_tail = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_tail->job_next = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_tail = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortejob_request_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_deque_job(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job_request_t *job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_head == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_job_tail == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job = port->fp_job_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_next == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(job == port->fp_job_tail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_head = job->job_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_priority_enque_job(fc_local_port_t *port, job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_job_tail == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_job_head == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_head = port->fp_job_tail = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_next = port->fp_job_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_job_head = job;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&port->fp_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_jobwait(job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!(job->job_flags & JOB_TYPE_FCTL_ASYNC));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_p(&job->job_fctl_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&job->job_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_jobdone(job_request_t *job)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_flags & JOB_TYPE_FCTL_ASYNC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (job->job_comp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte job->job_comp(job->job_cb_arg, job->job_result);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_job(job);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_v(&job->job_fctl_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Compare two WWNs.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The NAA can't be omitted for comparison.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Values:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if src == dst return 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if src > dst return 1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if src < dst return -1
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_wwn_cmp(la_wwn_t *src, la_wwn_t *dst)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t *l, *r;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int i;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint64_t wl, wr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang l = (uint8_t *)src;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang r = (uint8_t *)dst;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang for (i = 0, wl = 0; i < 8; i++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wl <<= 8;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wl |= l[i];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang for (i = 0, wr = 0; i < 8; i++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wr <<= 8;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wr |= r[i];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (wl > wr) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (wl == wr) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (-1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ASCII to Integer goodie with support for base 16, 10, 2 and 8
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_atoi(char *s, int base)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int val;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ch;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (val = 0; *s != '\0'; s++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (base) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 16:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*s >= '0' && *s <= '9') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - '0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (*s >= 'a' && *s <= 'f') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - 'a' + 10;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (*s >= 'A' && *s <= 'F') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - 'A' + 10;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 10:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*s < '0' || *s > '9') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - '0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 2:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*s < '0' || *s > '1') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - '0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 8:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*s < '0' || *s > '7') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ch = *s - '0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte val = (val * base) + ch;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (val);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create the fc_remote_port_t struct for the given port_wwn and d_id.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the struct already exists (and is "valid"), then use it. Before using
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it, the code below also checks: (a) if the d_id has changed, and (b) if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the device is maked as PORT_DEVICE_OLD.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If no fc_remote_node_t struct exists for the given node_wwn, then that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct is also created (and linked with the fc_remote_port_t).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The given fc_local_port_t struct is updated with the info on the new
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * struct(s). The d_id and pwwn hash tables in the port_wwn are updated.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The global node_hash_table[] is updated (if necessary).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_create_remote_port(fc_local_port_t *port, la_wwn_t *node_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t *port_wwn, uint32_t d_id, uchar_t recepient, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int invalid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *rnodep;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = fctl_get_remote_node_by_nwwn(node_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We found an fc_remote_node_t for the remote node -- see if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anyone has marked it as going away or gone.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte invalid = (rnodep->fd_flags == FC_REMOTE_NODE_INVALID) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&rnodep->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep == NULL || invalid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No valid remote node struct found -- create it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: this is the only place that this func is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = fctl_create_remote_node(node_wwn, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if there already is an fc_remote_port_t struct in existence
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * on the specified fc_local_port_t for the given pwwn. If so, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * grab a reference to it. The 'held' here just means that fp_mutex
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is held by the caller -- no reference counts are updated.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = fctl_get_remote_port_by_pwwn_mutex_held(port, port_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An fc_remote_port_t struct was found -- see if anyone has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * marked it as "invalid", which means that it is in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * process of going away & we don't want to use it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte invalid = (pd->pd_state == PORT_DEVICE_INVALID) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd == NULL || invalid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No fc_remote_port_t was found (or the existing one is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * marked as "invalid".) Allocate a new one and use that.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This call will also update the d_id and pwwn hash tables
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the given fc_local_port_t struct with the newly allocated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd = fctl_alloc_remote_port(port, port_wwn, d_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte recepient, sleep)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just give up if the allocation fails. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add the new fc_remote_port_t struct to the d_id and pwwn
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hash tables on the associated fc_local_port_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_remote_nodep = rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Retrieve a pointer to the fc_remote_node_t (i.e., remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node) specified by the given node_wwn. This looks in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * global fctl_nwwn_hash_table[]. The fd_numports reference
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * count in the fc_remote_node_t struct is incremented.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = fctl_lock_remote_node_by_nwwn(node_wwn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An existing and valid fc_remote_port_t struct already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * exists on the fc_local_port_t for the given pwwn.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pd->pd_remote_nodep != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_port_id.port_id != d_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A very unlikely occurance in a well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * behaved environment.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The existing fc_remote_port_t has a different
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * d_id than what we were given. This code will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update the existing one with the one that was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just given.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char string[(FCTL_WWN_SIZE(port_wwn) << 1) + 1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t old_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(port_wwn, string);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_id = pd->pd_port_id.port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "!fctl(%d): D_ID of a device"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " with PWWN %s changed. New D_ID = %x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " OLD D_ID = %x", port->fp_instance, string,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte d_id, old_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id = d_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Looks like we have to presume here that the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remote port could be something entirely different
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from what was previously existing & valid at this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pwwn.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_CHANGED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Record (update) the new d_id for the remote port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (pd->pd_type == PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OK at least the old & new d_id's match. So for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PORT_DEVICE_OLD, this assumes that the remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port had disappeared but now has come back.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update the pd_type and pd_state to put the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remote port back into service.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_enlist_did_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OK the old & new d_id's match, and the remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port struct is not marked as PORT_DEVICE_OLD, so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * presume that it's still the same device and is
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * still in good shape. Also this presumes that we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do not need to update d_id or pwwn hash tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* sanitize device values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_NOCHANGE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_state = PORT_DEVICE_VALID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep != pd->pd_remote_nodep) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rnodep != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (fctl_wwn_cmp(&pd->pd_remote_nodep->fd_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node_wwn) != 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Rut-roh, there is an fc_remote_node_t remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * node struct for the given node_wwn, but the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_port_t remote port struct doesn't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * know about it. This just prints a warning
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * message & fails the fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allocation (possible leak here?).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww1_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ww2_name[17];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pd->pd_remote_nodep->fd_node_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww1_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_wwn_to_str(node_wwn, ww2_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "fctl(%d) NWWN Mismatch: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Expected %s Got %s", port->fp_instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ww1_name, ww2_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Add the fc_remote_port_t onto the linked list of remote port
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devices associated with the given fc_remote_node_t (remote node).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_link_remote_port_to_remote_node(rnodep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Disassociate the given fc_local_port_t and fc_remote_port_t structs. Removes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_remote_port_t from the associated fc_remote_node_t. Also removes any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * references to the fc_remote_port_t from the d_id and pwwn tables in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * given fc_local_port_t. Deallocates the given fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns a count of the number of remaining fc_remote_port_t structs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * associated with the fc_remote_node_t struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If pd_ref_count in the given fc_remote_port_t is nonzero, then this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function just sets the pd->pd_aux_flags |= PD_NEEDS_REMOVAL and the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd->pd_type = PORT_DEVICE_OLD and lets some other function(s) worry about
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the cleanup. The function then also returns '1'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * instead of the actual number of remaining fc_remote_port_t structs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If there are no more remote ports on the remote node, return 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Otherwise, return non-zero.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_destroy_remote_port(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_node_t *rnodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rcount = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If pd_ref_count > 0, we can't pull the rug out from any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * current users of this fc_remote_port_t. We'll mark it as old
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and in need of removal. The same goes for any fc_remote_port_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that has a reference handle(s) in a ULP(s) but for which the ULP(s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have not yet been notified that the handle is no longer valid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (i.e., PD_GIVEN_TO_ULPS is set).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((pd->pd_ref_count > 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (pd->pd_aux_flags & PD_GIVEN_TO_ULPS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags |= PD_NEEDS_REMOVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_type = PORT_DEVICE_OLD;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the fc_remote_port_t from the linked list of remote
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports for the given fc_remote_node_t. This is only called
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * here and in fctl_destroy_all_remote_ports().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcount = fctl_unlink_remote_port_from_remote_node(rnodep, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
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
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deconstruct & free the fc_remote_port_t. This is only called
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * here and in fctl_destroy_all_remote_ports().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rcount);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This goes thru the d_id table on the given fc_local_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For each fc_remote_port_t found, this will:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Remove the fc_remote_port_t from the linked list of remote ports for
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the associated fc_remote_node_t. If the linked list goes empty, then this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tries to deconstruct & free the fc_remote_node_t (that also removes the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t from the global fctl_nwwn_hash_table[]).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Remove the fc_remote_port_t from the pwwn list on the given
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_local_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Deconstruct and free the fc_remote_port_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Removes the link to the fc_remote_port_t in the d_id table. Note, this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * does not appear to correctle decrement the d_id_count tho.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_destroy_all_remote_ports(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *rnodep;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct d_id_hash *head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < did_table_size; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head = &port->fp_did_table[index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (head->d_id_head != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->d_id_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if this remote port (fc_remote_port_t) has a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * reference to a remote node (fc_remote_node_t) in its
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pd->pd_remote_nodep pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rnodep != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An fc_remote_node_t reference exists. Remove
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_remote_port_t from the linked list of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remote ports for fc_remote_node_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_unlink_remote_port_from_remote_node(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rnodep, pd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The fd_numports reference count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the fc_remote_node_t has come
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * back as zero, so we can free the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fc_remote_node_t. This also means
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that the fc_remote_node_t was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removed from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_nwwn_hash_table[].
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will silently skip the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kmem_free() if either the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fd_numports is nonzero or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fd_port is not NULL in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fc_remote_node_t.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(rnodep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clean up the entry in the fc_local_port_t's pwwn
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table for the given fc_remote_port_t (i.e., the pd).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_pwwn_table(port, pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_aux_flags &= ~PD_IN_DID_QUEUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove the current entry from the d_id list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->d_id_head = pd->pd_did_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deconstruct & free the fc_remote_port_t (pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: this is only called here and in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fctl_destroy_remote_port_t().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_dealloc_remote_port(pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_is_wwn_zero(la_wwn_t *wwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (la_wwn_t); count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wwn->raw_wwn[count] != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_ulp_unsol_cb(fc_local_port_t *port, fc_unsol_buf_t *buf, uchar_t type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int data_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int check_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t claimed;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte claimed = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte check_type = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch ((buf->ub_frame.r_ctl) & R_CTL_ROUTING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_DEVICE_DATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data_cb = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_EXTENDED_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte check_type = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case R_CTL_FC4_SVC:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data_cb = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
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 return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (check_type && mod->mod_info->ulp_type != type) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_get_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FCTL_DISALLOW_CALLBACKS(ulp_port->port_dstate)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (data_cb == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = mod->mod_info->ulp_data_callback(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)port, buf, claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = mod->mod_info->ulp_els_callback(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (opaque_t)port, buf, claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS && claimed == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte claimed = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (claimed == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We should actually RJT since nobody claimed it.
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 } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
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}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Both fd_mutex and pd_mutex are held (in that order) coming in to this func
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * With all these mutexes held, we should make sure this function does not eat
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * up much time.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_copy_portmap_held(fc_portmap_t *map, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_did = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_hard_addr = pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_type = pd->pd_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(map->map_type <= PORT_DEVICE_DELETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pd->pd_fc4types, map->map_fc4_types, sizeof (pd->pd_fc4types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&node->fd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_nwwn = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_copy_portmap(fc_portmap_t *map, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_did = pd->pd_port_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_hard_addr = pd->pd_hard_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_state = pd->pd_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_type = pd->pd_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(map->map_type <= PORT_DEVICE_DELETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(pd->pd_fc4types, map->map_fc4_types, sizeof (pd->pd_fc4types));
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 map->map_nwwn = node->fd_node_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&node->fd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte map->map_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_update_host_ns_values(fc_local_port_t *port, fc_ns_cmd_t *ns_req)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ns_req->ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RFT_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *src;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *dst;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ns_rfc_type_t *rfc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rfc = (ns_rfc_type_t *)ns_req->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src = (uint32_t *)port->fp_fc4_types;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dst = (uint32_t *)rfc->rfc_types;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 8; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *src++ |= *dst++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSPN_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_spn_t *spn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spn = (ns_spn_t *)ns_req->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_namelen = spn->spn_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (spn->spn_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)spn + sizeof (ns_spn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_port_name, spn->spn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_RSNN_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_snn_t *snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snn = (ns_snn_t *)ns_req->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_namelen = snn->snn_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (snn->snn_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((caddr_t)snn + sizeof (ns_snn_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_sym_node_name, snn->snn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
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 rip = (ns_rip_t *)ns_req->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(rip->rip_ip_addr, port->fp_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rip->rip_ip_addr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
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 ipa = (ns_ipa_t *)ns_req->ns_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ipa->ipa_value, port->fp_ipa, sizeof (ipa->ipa_value));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_BADOBJECT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_retrieve_host_ns_values(fc_local_port_t *port, fc_ns_cmd_t *ns_req)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ns_req->ns_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GFT_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rfc_type_t *rfc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rfc = (ns_rfc_type_t *)ns_req->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_fc4_types, rfc->rfc_types,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rfc->rfc_types));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GSPN_ID: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_spn_t *spn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spn = (ns_spn_t *)ns_req->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spn->spn_len = port->fp_sym_port_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (spn->spn_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_sym_port_name, (caddr_t)spn +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_spn_t), spn->spn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GSNN_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_snn_t *snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snn = (ns_snn_t *)ns_req->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snn->snn_len = port->fp_sym_node_namelen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (snn->snn_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_sym_node_name, (caddr_t)snn +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ns_snn_t), snn->snn_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GIP_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_rip_t *rip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rip = (ns_rip_t *)ns_req->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_ip_addr, rip->rip_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (rip->rip_ip_addr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NS_GIPA_NN: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_ipa_t *ipa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipa = (ns_ipa_t *)ns_req->ns_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->fp_ipa, ipa->ipa_value, sizeof (ipa->ipa_value));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_BADOBJECT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_ns_req_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_alloc_ns_cmd(uint32_t cmd_len, uint32_t resp_len, uint32_t data_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t ns_flags, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_ns_req_t *ns_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd = kmem_zalloc(sizeof (*ns_cmd), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_buf = kmem_zalloc(cmd_len, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_buf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd, sizeof (*ns_cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_cmd_size = cmd_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_resp_size = resp_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (data_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_buf = kmem_zalloc(data_len, sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_data_buf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_buf && cmd_len) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd->ns_cmd_buf, cmd_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd, sizeof (*ns_cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_data_len = data_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns_cmd->ns_flags = ns_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ns_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_free_ns_cmd(fctl_ns_req_t *ns_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_cmd_size && ns_cmd->ns_cmd_buf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd->ns_cmd_buf, ns_cmd->ns_cmd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ns_cmd->ns_data_len && ns_cmd->ns_data_buf) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd->ns_data_buf, ns_cmd->ns_data_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ns_cmd, sizeof (*ns_cmd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_ulp_port_ioctl(fc_local_port_t *port, dev_t dev, int cmd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte intptr_t data, int mode, cred_t *credp, int *rval)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int save;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t claimed;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_ulp_module_t *mod;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_ulp_ports_t *ulp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte save = *rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rval = ENOTTY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_ulp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (claimed = 0, mod = fctl_ulp_modules; mod; mod = mod->mod_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&fctl_mod_ports_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulp_port = fctl_get_ulp_port(mod, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_mod_ports_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ulp_port == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FCTL_DISALLOW_CALLBACKS(ulp_port->port_dstate) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_port_ioctl == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ulp_port->port_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mod->mod_info->ulp_port_ioctl(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mod->mod_info->ulp_handle, (opaque_t)port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev, cmd, data, mode, credp, rval, claimed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FC_SUCCESS && claimed == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte claimed = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&fctl_ulp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = *rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *rval = save;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * raise power if necessary, and set the port busy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this may cause power to be raised, so no power related locks should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_busy_port(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fctl_busy_port(port));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_idle_port(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_copy_portmap(fc_portmap_t *map, opaque_t pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_copy_portmap(map, (fc_remote_port_t *)pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_npiv_port_num(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portsnum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = port->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!tmpport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (portsnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmpport != port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portsnum ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = tmpport->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (portsnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_local_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_get_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_t *fca_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpPort = phyport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPort = fca_port->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpPort == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(tmpPort->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn->raw_wwn, sizeof (la_wwn_t)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (tmpPort);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_npiv_port_list(opaque_t port_handle, char *pathList)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int portsnum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = port->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!tmpport || (port->fp_npiv_type == FC_NPIV_PORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (portsnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmpport != port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_pathname(tmpport->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &pathList[MAXPATHLEN * portsnum]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portsnum ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = tmpport->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (portsnum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_local_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_delete_npiv_port(fc_local_port_t *port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = port->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!tmpport || (port->fp_npiv_type == FC_NPIV_PORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmpport != port) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bcmp(tmpport->fp_service_params.nport_ww_name.raw_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn->raw_wwn, sizeof (la_wwn_t)) == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (tmpport->fp_npiv_state == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport->fp_npiv_state = FC_NPIV_DELETING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (tmpport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpport = tmpport->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the list of Adapters. On multi-ported adapters,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only ONE port on the adapter will be returned.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pathList should be (count * MAXPATHLEN) long.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The return value will be set to the number of
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * HBAs that were found on the system. If the value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is greater than count, the routine should be retried
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with a larger buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_adapter_paths(char *pathList, int count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *fca_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int in = 0, out = 0, check, skip, maxPorts = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t **portList;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *new_port, *stored_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_hba_fru_details_t *new_fru, *stored_fru;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(pathList != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* First figure out how many ports we have */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maxPorts ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now allocate a buffer to store all the pointers for comparisons */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte portList = kmem_zalloc(sizeof (fc_local_port_t *) * maxPorts, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte skip = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lock the new port for subsequent comparisons */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_port = fca_port->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&new_port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_fru = &new_port->fp_hba_port_attrs.hba_fru_details;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Filter out secondary ports from the list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (check = 0; check < out; check++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (portList[check] == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Guard against duplicates (should never happen) */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (portList[check] == fca_port->port_handle) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Same port */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang skip = 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Lock the already stored port for comparison */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang stored_port = portList[check];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&stored_port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang stored_fru =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &stored_port->fp_hba_port_attrs.hba_fru_details;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Are these ports on the same HBA? */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (new_fru->high == stored_fru->high &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang new_fru->low == stored_fru->low) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Now double check driver */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (strncmp(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang new_port->fp_hba_port_attrs.driver_name,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang stored_port->fp_hba_port_attrs.driver_name,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCHBA_DRIVER_NAME_LEN) == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* we don't need to grow the list */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang skip = 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* looking at a lower port index? */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (new_fru->port_index <
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang stored_fru->port_index) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Replace the port in list */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &stored_port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (new_port->fp_npiv_type ==
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_NPIV_PORT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang portList[check] = new_port;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } /* Else, just skip this port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&stored_port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&new_port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!skip) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Either this is the first port for this HBA, or
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * it's a secondary port and we haven't stored the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * primary/first port for that HBA. In the latter case,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * will just filter it out as we proceed to loop.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fca_port->port_handle->fp_npiv_type ==
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_NPIV_PORT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang portList[out++] = fca_port->port_handle;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (out <= count) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang for (in = 0; in < out; in++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) ddi_pathname(portList[in]->fp_port_dip,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &pathList[MAXPATHLEN * in]);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(portList, sizeof (*portList) * maxPorts);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (out);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint32_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_get_rscn_count(opaque_t port_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = (fc_local_port_t *)port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count = port->fp_rscn_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is a very similar to fctl_add_orphan except that it expects
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * that the fp_mutex and pd_mutex of the pd passed in are held coming in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that there is a lock hierarchy here (fp_mutex should be held first) but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * since this function could be called with a different pd's pd_mutex held, we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should take care not to release fp_mutex in this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_add_orphan_held(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *orphan;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&pd->pd_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pwwn = pd->pd_port_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (orp = port->fp_orphan_list; orp != NULL; orp = orp->orp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&orp->orp_pwwn, &pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan = kmem_zalloc(sizeof (*orphan), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orphan) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_tstamp = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_orphan_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_orphan_count > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_next = port->fp_orphan_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list = orphan;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_add_orphan(fc_local_port_t *port, fc_remote_port_t *pd, int sleep)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte la_wwn_t pwwn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *orphan;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
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 for (orp = port->fp_orphan_list; orp != NULL; orp = orp->orp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&orp->orp_pwwn, &pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan = kmem_zalloc(sizeof (*orphan), sleep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (orphan != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_pwwn = pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_tstamp = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_orphan_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_orphan_count > 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte orphan->orp_next = port->fp_orphan_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list = orphan;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_remove_if_orphan(fc_local_port_t *port, la_wwn_t *pwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = FC_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_orphan_t *prev = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (orp = port->fp_orphan_list; orp != NULL; orp = orp->orp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&orp->orp_pwwn, pwwn) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev->orp_next = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_orphan_list == orp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_list = orp->orp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_orphan_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = FC_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev = orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(orp, sizeof (*orp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_print_if_not_orphan(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char ww_name[17];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_wwn_t pwwn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_orphan_t *orp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
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 for (orp = port->fp_orphan_list; orp != NULL; orp = orp->orp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_wwn_cmp(&orp->orp_pwwn, &pwwn) == 0) {
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 fc_wwn_to_str(&pwwn, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fctl(%d): N_x Port with D_ID=%x, PWWN=%s"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " disappeared from fabric", port->fp_instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd->pd_port_id.port_id, ww_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_link_reset_done(opaque_t port_handle, uchar_t result)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
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 fctl_idle_port(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_error(int fc_errno, char **errmsg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (fc_errlist) /
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (fc_errlist[0]); count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fc_errlist[count].fc_errno == fc_errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *errmsg = fc_errlist[count].fc_errname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *errmsg = fctl_undefined;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return number of successful translations.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Anybody with some userland programming experience would have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * figured it by now that the return value exactly resembles that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of scanf(3c). This function returns a count of successful
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * translations. It could range from 0 (no match for state, reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * action, expln) to 4 (successful matches for all state, reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * action, expln) and where translation isn't successful into a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * friendlier message the relevent field is set to "Undefined"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_pkt_error(fc_packet_t *pkt, char **state, char **reason,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **action, char **expln)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt_error_t *error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt_reason_t *reason_b; /* Base pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt_action_t *action_b; /* Base pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_pkt_expln_t *expln_b; /* Base pointer */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *state = *reason = *action = *expln = fctl_undefined;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = sizeof (fc_pkt_errlist) / sizeof fc_pkt_errlist[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < len; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = fc_pkt_errlist + index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pkt->pkt_state == error->pkt_state) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *state = error->pkt_msg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte reason_b = error->pkt_reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte action_b = error->pkt_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte expln_b = error->pkt_expln;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (reason_b != NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte reason_b->reason_val != FC_REASON_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (reason_b->reason_val == pkt->pkt_reason) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *reason = reason_b->reason_msg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte reason_b++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (action_b != NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte action_b->action_val != FC_ACTION_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (action_b->action_val == pkt->pkt_action) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *action = action_b->action_msg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte action_b++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (expln_b != NULL &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte expln_b->expln_val != FC_EXPLN_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (expln_b->expln_val == pkt->pkt_expln) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *expln = expln_b->expln_msg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte expln_b++;
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 * Remove all port devices that are marked OLD, remove
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * corresponding node devices (fc_remote_node_t)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_remove_oldies(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int initiator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_node_t *node;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *old_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_remote_port_t *last_pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Nuke all OLD devices
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&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 last_pd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_type != PORT_DEVICE_OLD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remove this from the PWWN hash table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_pd = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = old_pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (last_pd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(old_pd == head->pwwn_head);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_head = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_pd->pd_wwn_hnext = pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte head->pwwn_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure we tie fp_dev_count to the size of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pwwn_table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_dev_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_pd->pd_wwn_hnext = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_delist_did_table(port, old_pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte node = old_pd->pd_remote_nodep;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(node != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte initiator = (old_pd->pd_recepient ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PD_PLOGI_INITIATOR) ? 1 : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&old_pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_IS_TOP_SWITCH(port->fp_topology) && initiator) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fctl_add_orphan(port, old_pd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_destroy_remote_port(port, old_pd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_destroy_remote_node(node);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_check_alpa_list(fc_local_port_t *port, fc_remote_port_t *pd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_topology == FC_TOP_PRIVATE_LOOP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fctl_is_alpa_present(port, pd->pd_port_id.port_id) == FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!fctl(%d): AL_PA=0x%x doesn't exist in LILP map",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_instance, pd->pd_port_id.port_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_is_alpa_present(fc_local_port_t *port, uchar_t alpa)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(port->fp_topology == FC_TOP_PRIVATE_LOOP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (index = 0; index < port->fp_lilp_map.lilp_length; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_lilp_map.lilp_alpalist[index] == alpa) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_lookup_pd_by_did(fc_local_port_t *port, uint32_t d_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang 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
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (pd != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd->pd_port_id.port_id == d_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&pd->pd_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * trace debugging
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_debug(fc_trace_logq_t *logq, caddr_t name, int dflag, int dlevel,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int errno, const char *fmt, ...)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang char buf[FC_MAX_TRACE_BUF_LEN + 3]; /* 3 is for "\n" */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *bufptr = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_list ap;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dlevel & dflag) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (name) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = snprintf(buf, FC_MAX_TRACE_BUF_LEN + 1, "%d=>%s::",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang logq->il_id++, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = snprintf(buf, FC_MAX_TRACE_BUF_LEN + 1, "%d=>trace::",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang logq->il_id++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt < FC_MAX_TRACE_BUF_LEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_start(ap, fmt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt += vsnprintf(buf + cnt, FC_MAX_TRACE_BUF_LEN + 1 - cnt,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fmt, ap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_end(ap);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt > FC_MAX_TRACE_BUF_LEN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = FC_MAX_TRACE_BUF_LEN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno && (cnt < FC_MAX_TRACE_BUF_LEN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt += snprintf(buf + cnt, FC_MAX_TRACE_BUF_LEN + 1 - cnt,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "error=0x%x\n", errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(buf + cnt, FC_MAX_TRACE_BUF_LEN + 3 - cnt, "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (logq && (dlevel & FC_TRACE_LOG_BUF) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_logmsg(logq, buf, dlevel);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We do not want to print the log numbers that appear as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * random numbers at the console and messages files, to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the user.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bufptr = strchr(buf, '>')) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We would have added the a string with "=>" above and so,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ideally, we should not get here at all. But, if we do,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we'll just use the full buf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bufptr = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bufptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (dlevel & FC_TRACE_LOG_MASK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRACE_LOG_CONSOLE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "%s", bufptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRACE_LOG_CONSOLE_MSG:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "%s", bufptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case FC_TRACE_LOG_MSG:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "!%s", bufptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function can block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_logq_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_alloc_logq(int maxsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_logq_t *logq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq = kmem_zalloc(sizeof (*logq), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&logq->il_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_hiwat = maxsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_flags |= FC_TRACE_LOGQ_V2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (logq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_free_logq(fc_trace_logq_t *logq)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (logq->il_msgh) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_freemsg(logq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(logq, sizeof (*logq));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_logmsg(fc_trace_logq_t *logq, caddr_t buf, int level)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int qfull = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_dmsg_t *dmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmsg = kmem_alloc(sizeof (*dmsg), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dmsg == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_afail++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gethrestime(&dmsg->id_time);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmsg->id_size = strlen(buf) + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmsg->id_buf = kmem_alloc(dmsg->id_size, KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dmsg->id_buf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dmsg, sizeof (*dmsg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_afail++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(buf, dmsg->id_buf, strlen(buf));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmsg->id_buf[strlen(buf)] = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_size += dmsg->id_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (logq->il_size >= logq->il_hiwat) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte qfull = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (qfull) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_freemsg(logq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmsg->id_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (logq->il_msgt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_msgt->id_next = dmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(logq->il_msgh == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_msgh = dmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_msgt = dmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&logq->il_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_trace_freemsg(fc_trace_logq_t *logq)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_trace_dmsg_t *dmsg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&logq->il_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dmsg = logq->il_msgh) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_msgh = dmsg->id_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (logq->il_msgh == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_msgt = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte logq->il_size -= dmsg->id_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dmsg->id_buf, dmsg->id_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dmsg, sizeof (*dmsg));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(logq->il_msgt == NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Used by T11 FC-HBA to fetch discovered ports by index.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns NULL if the index isn't valid.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_lookup_pd_by_index(fc_local_port_t *port, uint32_t index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int outer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int match = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_remote_port_t *pd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (outer = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang outer < pwwn_table_size && match <= index;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang outer++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang head = &port->fp_pwwn_table[outer];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pd = head->pwwn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pd != NULL) match ++;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (pd != NULL && match <= index) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pd = pd->pd_wwn_hnext;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (pd != NULL) match ++;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (pd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search for a matching Node or Port WWN in the discovered port list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_lookup_pd_by_wwn(fc_local_port_t *port, la_wwn_t wwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pwwn_hash *head;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang 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
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang while (pd != NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&pd->pd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (bcmp(pd->pd_port_name.raw_wwn, wwn.raw_wwn,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sizeof (la_wwn_t)) == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&pd->pd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (pd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (bcmp(pd->pd_remote_nodep->fd_node_name.raw_wwn,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wwn.raw_wwn, sizeof (la_wwn_t)) == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&pd->pd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (pd);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&pd->pd_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang pd = pd->pd_wwn_hnext;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No match */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Count the number of ports on this adapter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine will walk the port list and count up the number of adapters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with matching fp_hba_port_attrs.hba_fru_details.high and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fp_hba_port_attrs.hba_fru_details.low.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port->fp_mutex must not be held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_count_fru_ports(fc_local_port_t *port, int npivflag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_hba_fru_details_t *fru;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *fca_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpPort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru = &port->fp_hba_port_attrs.hba_fru_details;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Detect FCA drivers that don't support linking HBA ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fru->high == 0 && fru->low == 0 && fru->port_index == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang tmpPort = fca_port->port_handle;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (tmpPort == port) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If an FCA driver returns unique fru->high and fru->low for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ports on the same card, there is no way for the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * layer to determine that the two ports on the same FRU. So,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the discovery of the ports on a same FRU is limited to what
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the FCA driver can report back.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpPort->fp_hba_port_attrs.hba_fru_details.high ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru->high &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPort->fp_hba_port_attrs.hba_fru_details.low ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru->low) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now double check driver */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(port->fp_hba_port_attrs.driver_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPort->fp_hba_port_attrs.driver_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCHBA_DRIVER_NAME_LEN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!npivflag ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (tmpPort->fp_npiv_type != FC_NPIV_PORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* Else, different FCA driver */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* Else not the same HBA FRU */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_fca_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_local_port_list_add(fc_fca_port_t *list, fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_t *tmp = list, *newentry = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newentry = kmem_zalloc(sizeof (fc_fca_port_t), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (newentry == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newentry->port_handle = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (newentry);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmp->port_next != NULL) tmp = tmp->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp->port_next = newentry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_local_port_list_free(fc_fca_port_t *list)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_t *tmp = list, *nextentry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (tmp != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nextentry = tmp->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(tmp, sizeof (*tmp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp = nextentry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fetch another port on the HBA FRU based on index.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns NULL if index not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port->fp_mutex must not be held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_local_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_get_adapter_port_by_index(fc_local_port_t *port, uint32_t port_index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_hba_fru_details_t *fru;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_fca_port_t *fca_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *tmpPort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_fca_port_t *list = NULL, *tmpEntry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *phyPort, *virPort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int index, phyPortNum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru = &port->fp_hba_port_attrs.hba_fru_details;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Are we looking for this port? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fru->port_index == port_index) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Detect FCA drivers that don't support linking HBA ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fru->high == 0 && fru->low == 0 && fru->port_index == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list = fctl_local_port_list_add(list, port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyPortNum++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop through all known ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (fca_port = fctl_fca_portlist; fca_port != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fca_port = fca_port->port_next) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang tmpPort = fca_port->port_handle;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (tmpPort == port) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Skip the port that was passed in as the argument */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang continue;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&tmpPort->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* See if this port is on the same HBA FRU (fast check) */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (tmpPort->fp_hba_port_attrs.hba_fru_details.high ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru->high &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpPort->fp_hba_port_attrs.hba_fru_details.low ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fru->low) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Now double check driver (slower check) */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (strncmp(port->fp_hba_port_attrs.driver_name,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang tmpPort->fp_hba_port_attrs.driver_name,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCHBA_DRIVER_NAME_LEN) == 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fru =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &tmpPort->fp_hba_port_attrs.hba_fru_details;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Check for the matching port_index */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((tmpPort->fp_npiv_type != FC_NPIV_PORT) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (fru->port_index == port_index)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* Found it! */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&tmpPort->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&port->fp_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&fctl_port_lock);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fctl_local_port_list_free(list);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (tmpPort);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (tmpPort->fp_npiv_type != FC_NPIV_PORT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) fctl_local_port_list_add(list,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang tmpPort);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang phyPortNum++;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } /* Else, different FCA driver */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } /* Else not the same HBA FRU */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&tmpPort->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* scan all physical port on same chip to find virtual port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpEntry = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index = phyPortNum - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte virPort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (index < port_index) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmpEntry == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (virPort == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phyPort = tmpEntry->port_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte virPort = phyPort->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (virPort == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpEntry = tmpEntry->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte virPort = virPort->fp_port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (virPort == phyPort) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmpEntry = tmpEntry->port_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte virPort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&fctl_port_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fctl_local_port_list_free(list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (virPort) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (virPort);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_busy_port(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_soft_state & FP_SOFT_NO_PMCOMP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If fctl_busy_port() is called before we've registered our
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PM components, we return success. We need to be aware of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this because the caller will eventually call fctl_idle_port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This wouldn't be a problem except that if we have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * registered our PM components in the meantime, we will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then be idling a component that was never busied. PM
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * will be very unhappy if we do this. Thus, we keep
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * track of this with port->fp_pm_busy_nocomp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy_nocomp++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_busy_component(port->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_COMPONENT) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pm_level == FP_PM_PORT_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_raise_power(port->fp_port_dip, FP_PM_COMPONENT,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_PORT_UP) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) pm_idle_component(port->fp_port_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FP_PM_COMPONENT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefctl_idle_port(fc_local_port_t *port)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!MUTEX_HELD(&port->fp_mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If port->fp_pm_busy_nocomp is > 0, that means somebody had
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called fctl_busy_port prior to us registering our PM components.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In that case, we just decrement fp_pm_busy_nocomp and return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (port->fp_pm_busy_nocomp > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy_nocomp--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->fp_pm_busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&port->fp_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) pm_idle_component(port->fp_port_dip, FP_PM_COMPONENT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fctl_tc_timer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Resets the value of the timed counter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *tc Timed counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: Nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Context: Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfctl_tc_timer(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte timed_counter_t *tc = (timed_counter_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc->sig == tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tc->active) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->active = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->counter = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fctl_tc_constructor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Constructs a timed counter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *tc Address where the timed counter will reside.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * max_value Maximum value the counter is allowed to take.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * timer Number of microseconds after which the counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will be reset. The timer is started when the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value of the counter goes from 0 to 1.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: Nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Context: Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfctl_tc_constructor(timed_counter_t *tc, uint32_t max_value, clock_t timer)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc->sig != tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(tc, sizeof (*tc));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&tc->mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->timer = drv_usectohz(timer);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->active = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->maxed_out = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->max_value = max_value;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->sig = tc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fctl_tc_destructor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Destroyes a timed counter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *tc Timed counter to destroy.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: Nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Context: Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfctl_tc_destructor(timed_counter_t *tc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc->sig == tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!mutex_owned(&tc->mutex));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tc->active) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->active = B_FALSE;
1641617f6cce96286522a449e1412c6279a956c7Sriram Popuri mutex_exit(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tc->tid);
1641617f6cce96286522a449e1412c6279a956c7Sriram Popuri mutex_enter(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->sig = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fctl_tc_increment
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Increments a timed counter
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *tc Timed counter to increment.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: B_TRUE Counter reached the max value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * B_FALSE Counter hasn't reached the max value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Context: Kernel or interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteboolean_t
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfctl_tc_increment(timed_counter_t *tc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc->sig == tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!tc->maxed_out) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Hasn't maxed out yet. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++tc->counter;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tc->counter >= tc->max_value) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just maxed out. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->maxed_out = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!tc->active) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->tid = timeout(fctl_tc_timer, tc, tc->timer);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->active = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (tc->maxed_out);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function: fctl_tc_reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Description: Resets a timed counter. The caller of this function has to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to make sure that while in fctl_tc_reset() fctl_tc_increment()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is not called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Arguments: *tc Timed counter to reset.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return Value: 0 Counter reached the max value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not 0 Counter hasn't reached the max value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Context: Kernel or interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfctl_tc_reset(timed_counter_t *tc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(tc->sig == tc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->counter = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->maxed_out = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tc->active) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tc->active = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) untimeout(tc->tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&tc->mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefc_ulp_log_device_event(opaque_t port_handle, int type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fc_local_port_t *port = port_handle;
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 return;
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 (type == FC_ULP_DEVICE_ONLINE) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ESC_SUNFC_DEVICE_ONLINE : ESC_SUNFC_DEVICE_OFFLINE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte attr_list, NULL, DDI_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteerror:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvlist_free(attr_list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}