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/*
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
de710d24d2fae4468e64da999e1d952a247f142cJosef 'Jeff' Sipek#include <sys/sysmacros.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sunddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/modctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/scsi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/impl/scsi_reset_notify.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/disp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/byteorder.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/varargs.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/atomic.h>
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer#include <sys/sdt.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/stmf_ioctl.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/portif.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/fct.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include <sys/fctio.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "fct_impl.h"
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "discovery.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t fct_handle_local_port_event(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t fct_walk_discovery_queue(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t fct_process_els(fct_i_local_port_t *iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t fct_send_accrjt(fct_cmd_t *cmd, uint8_t accrjt,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t reason, uint8_t expl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t fct_link_init_complete(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t fct_complete_previous_li_cmd(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t fct_sol_plogi(fct_i_local_port_t *iport, uint32_t id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t **ret_ppcmd, int implicit);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t fct_sol_ct(fct_i_local_port_t *iport, uint32_t id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t **ret_ppcmd, uint16_t opcode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t fct_ns_scr(fct_i_local_port_t *iport, uint32_t id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t **ret_ppcmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic disc_action_t fct_check_cmdlist(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic disc_action_t fct_check_solcmd_queue(fct_i_local_port_t *iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void fct_rscn_verify(fct_i_local_port_t *iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *rscn_req_payload, uint32_t rscn_req_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid fct_gid_cb(fct_i_cmd_t *icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortechar *fct_els_names[] = { 0, "LS_RJT", "ACC", "PLOGI", "FLOGI", "LOGO",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ABTX", "RCS", "RES", "RSS", "RSI", "ESTS",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ESTC", "ADVC", "RTV", "RLS",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x10 */ "ECHO", "TEST", "RRQ", "REC", "SRR", 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x20 */ "PRLI", "PRLO", "SCN", "TPLS",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "TPRLO", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x50 */ "PDISC", "FDISC", "ADISC", "RNC", "FARP",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x60 */ "FAN", "RSCN", "SCR", 0, 0, 0, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0x70 */ "LINIT", "LPC", "LSTS", 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "RNID", "RLIR", "LIRR", 0, 0, 0, 0, 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern uint32_t fct_rscn_options;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: if anybody drops the iport_worker_lock then they should not return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DISC_ACTION_NO_WORK. Which also means, dont drop the lock if you have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nothing to do. Or else return DISC_ACTION_RESCAN or DISC_ACTION_DELAY_RESCAN.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * But you cannot be infinitly returning those so have some logic to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * determine that there is nothing to do without dropping the lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_port_worker(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = (fct_local_port_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t suggested_action;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t dl, short_delay, long_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int64_t tmp_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cmdcheck_clock = ddi_get_lbolt() +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(FCT_CMDLIST_CHECK_SECONDS * 1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte short_delay = drv_usectohz(10000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte long_delay = drv_usectohz(1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "iport is %p", iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Discovery loop */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags, IPORT_WORKER_RUNNING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((iport->iport_flags & IPORT_TERMINATE_WORKER) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action = DISC_ACTION_NO_WORK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Local port events are of the highest prioriy
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_event_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_handle_local_port_event(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We could post solicited ELSes to discovery queue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * solicited CT will be processed inside fct_check_solcmd_queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_solcmd_queue) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_check_solcmd_queue(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All solicited and unsolicited ELS will be handled here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rpwe_head) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_walk_discovery_queue(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We only process it when there's no outstanding link init CMD
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_state == PORT_STATE_LINK_INIT_START) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(iport->iport_li_state & (LI_STATE_FLAG_CMD_WAITING |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LI_STATE_FLAG_NO_LI_YET))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_process_link_init(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We process cmd aborting in the end
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_abort_queue) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_cmd_terminator(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check cmd max/free
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_cmdcheck_clock <= ddi_get_lbolt()) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_check_cmdlist(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cmdcheck_clock = ddi_get_lbolt() +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(FCT_CMDLIST_CHECK_SECONDS * 1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_max_active_ncmds = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_offline_prstate != FCT_OPR_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= fct_handle_port_offline(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (suggested_action & DISC_ACTION_RESCAN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (suggested_action & DISC_ACTION_DELAY_RESCAN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is not very optimum as whoever returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DISC_ACTION_DELAY_RESCAN must have dropped the lock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and more things might have queued up. But since
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we are only doing small delays, it only delays
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * things by a few ms, which is okey.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (suggested_action & DISC_ACTION_USE_SHORT_DELAY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl = short_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dl = long_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte IPORT_WORKER_DOING_TIMEDWAIT);
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&iport->iport_worker_cv,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &iport->iport_worker_lock, dl, TR_CLOCK_TICK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IPORT_WORKER_DOING_TIMEDWAIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte IPORT_WORKER_DOING_WAIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_delay = (int64_t)(iport->iport_cmdcheck_clock -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_lbolt());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp_delay < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_delay = (int64_t)short_delay;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&iport->iport_worker_cv,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &iport->iport_worker_lock, (clock_t)tmp_delay,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni TR_CLOCK_TICK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IPORT_WORKER_DOING_WAIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags, ~IPORT_WORKER_RUNNING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *topologies[] = { "Unknown", "Direct Pt-to-Pt", "Private Loop",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Unknown", "Unknown", "Fabric Pt-to-Pt",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Public Loop" };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_li_to_txt(fct_link_info_t *li, char *topology, char *speed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t s = li->port_speed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (li->port_topology > PORT_TOPOLOGY_PUBLIC_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(topology, "Invalid %02x", li->port_topology);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(topology, topologies[li->port_topology]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
de710d24d2fae4468e64da999e1d952a247f142cJosef 'Jeff' Sipek if ((s == 0) || ((s & 0xf00) != 0) || !ISP2(s)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte speed[0] = '?';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang } else if (s == PORT_SPEED_10G) {
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[0] = '1';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[1] = '0';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[2] = 'G';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[3] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte speed[0] = '0' + li->port_speed;
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[1] = 'G';
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang speed[2] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * discovery lock held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX: Implement command cleanup upon Link down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX: Implement a clean start and FC-GS registrations upon Link up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ================ Local Port State Machine ============
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * <hba fatal> <Link up>---|
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | v
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | <Start>--->[LINK_DOWN]--->[LINK_INIT_START]--->[LINK_INIT_DONE]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | ^ ^ ^ | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |---| | |--<Link down> |-| |---><Link Reset><--|
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | | | v | v
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * |->[FATAL_CLEANING] [LINK_DOWN_CLEANING]--->[LINK_UP_CLEANING]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ^
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * |--<Link up>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * =======================================================
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An explicit port_online() is only allowed in LINK_DOWN state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * An explicit port_offline() is only allowed in LINKDOWN and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LINK_INIT_DONE state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_local_port_event(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t ret = DISC_ACTION_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_event_t *in;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t old_state, new_state, new_bits;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int dqueue_and_free = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int retry_implicit_logo = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_event_head == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_NO_WORK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte in = iport->iport_event_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer if (in->event_type == FCT_EVENT_LINK_UP) {
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_1(link__up, fct_i_local_port_t, iport);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer } else if (in->event_type == FCT_EVENT_LINK_DOWN) {
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_1(link__down, fct_i_local_port_t, iport);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer }
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Calculate new state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = iport->iport_link_state;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (in->event_type == FCT_EVENT_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_DOWN_CLEANING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (in->event_type == FCT_EVENT_LINK_UP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_state == PORT_STATE_LINK_DOWN_CLEANING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_UP_CLEANING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (iport->iport_link_state == PORT_STATE_LINK_DOWN)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_INIT_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else { /* This should not happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Link up received when link state was"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%x, Ignoring...", iport->iport_link_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (in->event_type == FCT_I_EVENT_CLEANUP_POLL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!fct_local_port_cleanup_done(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_cleanup_retry >= 3) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_cleanup_retry = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retry_implicit_logo = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_cleanup_retry++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dqueue_and_free = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = DISC_ACTION_DELAY_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_STATE_LINK_DOWN_CLEANING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (iport->iport_link_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_STATE_LINK_UP_CLEANING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_INIT_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* This should not have happened */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "port state changed to %x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "during cleanup", iport->iport_link_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_DOWN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (in->event_type == FCT_EVENT_LINK_RESET) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link reset is only allowed when we are Online */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_state & S_LINK_ONLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_UP_CLEANING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (in->event_type == FCT_I_EVENT_LINK_INIT_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_state == PORT_STATE_LINK_INIT_START) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_state = PORT_STATE_LINK_INIT_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_bits = iport->iport_link_state ^
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan (iport->iport_link_state | new_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte old_state = iport->iport_link_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_state = new_state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "port state change from %x to %x",
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan old_state, new_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_bits & S_PORT_CLEANUP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_implicitly_logo_all(iport, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(iport->iport_port,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_I_EVENT_CLEANUP_POLL, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (retry_implicit_logo) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_implicitly_logo_all(iport, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_bits & S_INIT_LINK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_link_info_t *li = &iport->iport_link_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t li_ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state |= LI_STATE_FLAG_NO_LI_YET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(li, sizeof (*li));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((li_ret = iport->iport_port->port_get_link_info(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_port, li)) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "iport-%p: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port_get_link_info failed, ret %llx, forcing "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "link down.", iport, li_ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(iport->iport_port,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_EVENT_LINK_DOWN, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_login_retry = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This will reset LI_STATE_FLAG_NO_LI_YET */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&iport->iport_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan IPORT_ALLOW_UNSOL_FLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_local_port_event(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ESC_SUNFC_PORT_ONLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (new_bits & S_RCVD_LINK_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_local_port_event(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ESC_SUNFC_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (in && dqueue_and_free) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_event_head = in->event_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_event_head == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_event_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(in, sizeof (*in));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_lport_has_bigger_wwn(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *l, *r;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t wl, wr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte l = iport->iport_port->port_pwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte r = iport->iport_link_info.port_rpwwn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0, wl = 0; i < 8; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wl <<= 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wl |= l[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0, wr = 0; i < 8; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wr <<= 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wr |= r[i];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wl > wr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_do_flogi(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_flogi_xchg_t fx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int force_link_down = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_retry = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_1(fabric__login__start, fct_i_local_port_t, iport);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&fx, sizeof (fx));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_op = ELS_OP_FLOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_login_retry == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_sec_timeout = 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_sec_timeout = 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_info.port_topology & PORT_TOPOLOGY_PRIVATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_sid = iport->iport_link_info.portid & 0xFF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_did = 0xFFFFFE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_nwwn, fx.fx_nwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_pwwn, fx.fx_pwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = iport->iport_port->port_flogi_xchg(iport->iport_port, &fx);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (IPORT_FLOGI_DONE(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The unsolicited path finished it. */
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FCT_NOT_FOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_info.port_topology &
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan PORT_TOPOLOGY_PRIVATE_LOOP) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This is a private loop. There is no switch. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.port_no_fct_flogi = 1;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is really an error. This means we cannot init the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * link. Lets force the link to go down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_link_down = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((ret == FCT_SUCCESS) && (fx.fx_op == ELS_OP_LSRJT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fx.fx_rjt_reason == 5) || (fx.fx_rjt_reason == 0xe) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((fx.fx_rjt_reason == 9) && (fx.fx_rjt_expl == 0x29))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_retry = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_link_down = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ret == STMF_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_retry = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_link_down = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_retry) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_login_retry++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_login_retry >= 5)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_link_down = 1;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (force_link_down) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "iport-%p: flogi xchg failed. "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Forcing link down, ret=%llx login_retry=%d ret_op=%d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "reason=%d expl=%d", iport, ret, iport->iport_login_retry,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx.fx_op, fx.fx_rjt_reason, fx.fx_rjt_expl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(iport->iport_port, FCT_EVENT_LINK_DOWN, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer goto done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FLOGI succeeded. Update local port state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(fx.fx_op == ELS_OP_ACC);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fx.fx_nwwn, iport->iport_link_info.port_rnwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fx.fx_pwwn, iport->iport_link_info.port_rpwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fx.fx_fport) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.port_topology |=
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan PORT_TOPOLOGY_FABRIC_BIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.portid = fx.fx_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.port_fct_flogi_done = 1;
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramerdone:
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_1(fabric__login__end,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_local_port_t, iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called by FCAs to handle unsolicited FLOGIs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_rcvd_flogi(fct_local_port_t *port, fct_flogi_xchg_t *fx)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_flags & IPORT_ALLOW_UNSOL_FLOGI) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((iport->iport_flags & IPORT_ALLOW_UNSOL_FLOGI) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iport->iport_link_state != PORT_STATE_LINK_INIT_START) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((iport->iport_li_state & LI_STATE_MASK) > LI_STATE_N2N_PLOGI)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_link_info.port_fct_flogi_done == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.port_fct_flogi_done = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fx->fx_pwwn, iport->iport_link_info.port_rpwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fx->fx_nwwn, iport->iport_link_info.port_rnwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx->fx_op = ELS_OP_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t = fx->fx_sid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx->fx_sid = fx->fx_did;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fx->fx_did = t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_pwwn, fx->fx_pwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(iport->iport_port->port_nwwn, fx->fx_nwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iport_li_state can only be changed here and local_event
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_link_init(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *pname = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t elsop = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t ctop = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t wkdid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int implicit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int force_login = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t ret = DISC_ACTION_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_link_info_t *li = &iport->iport_link_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char topo[24], speed[4];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecheck_state_again:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (iport->iport_li_state & LI_STATE_MASK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_FLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Is FLOGI even needed or already done ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_info.port_no_fct_flogi) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (IPORT_FLOGI_DONE(iport))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_do_flogi(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_FINI_TOPOLOGY:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_li_to_txt(li, topo, speed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_NOTE, "%s LINK UP, portid %x, topology %s,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "speed %s", iport->iport_alias, li->portid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte topo, speed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (li->port_topology !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_old_topology) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_nrps) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rehash it if change from fabric to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none fabric, vice versa
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((li->port_topology ^
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_old_topology) &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PORT_TOPOLOGY_FABRIC_BIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_rehash(iport);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_old_topology = li->port_topology;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Skip next level if topo is not N2N */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (li->port_topology != PORT_TOPOLOGY_PT_TO_PT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state += 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IPORT_ALLOW_UNSOL_FLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_login_retry = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_cmd_timeout = ddi_get_lbolt() +
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan drv_usectohz(25 * 1000000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_N2N_PLOGI:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(IPORT_FLOGI_DONE(iport));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iport->iport_link_info.port_topology ==
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan PORT_TOPOLOGY_PT_TO_PT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_state & LI_STATE_FLAG_CMD_RETCHECK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state &= ~LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_comp_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_login_retry++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_login_retry >= 3) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Failing"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " to PLOGI to remote port in N2N "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " ret=%llx, forcing link down",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(iport->iport_port,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_EVENT_LINK_DOWN, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Find out if we need to do PLOGI at all */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_nrps_login) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iport->iport_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IPORT_ALLOW_UNSOL_FLOGI);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() >= iport->iport_li_cmd_timeout) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!fct_lport_has_bigger_wwn(iport))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Cant wait forever */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "N2N: Remote port is "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "not logging in, forcing from our side");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_login = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte force_login = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (force_login || fct_lport_has_bigger_wwn(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elsop = ELS_OP_PLOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wkdid = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.portid = 0xEF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte implicit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state |= LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = DISC_ACTION_DELAY_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_FCLOGIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_state & LI_STATE_FLAG_CMD_RETCHECK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state &= ~LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_comp_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fabric controller login failed. Just skip all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the fabric controller related cmds.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_DO_SCR + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Good. Now lets go to next state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!IPORT_IN_NS_TOPO(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_DO_SCR + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elsop = ELS_OP_PLOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wkdid = FS_FABRIC_CONTROLLER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte implicit = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We want to come back in the same state and check its ret
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We can't modify the state here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state |= LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_SCR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elsop = ELS_OP_SCR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wkdid = FS_FABRIC_CONTROLLER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We dont care about success of this state. Just go to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * next state upon completion.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_NSLOGIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_state & LI_STATE_FLAG_CMD_RETCHECK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state &= ~LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_li_comp_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_DO_RSNN + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!IPORT_IN_NS_TOPO(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state = LI_STATE_DO_RSNN + 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elsop = ELS_OP_PLOGI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wkdid = FS_NAME_SERVER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state |= LI_STATE_FLAG_CMD_RETCHECK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CT state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_RNN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctop = NS_RNN_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_RCS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctop = NS_RCS_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_RFT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctop = NS_RFT_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_RSPN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if we need skip the state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pname = iport->iport_port->port_sym_port_name !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL ? iport->iport_port->port_sym_port_name : NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pname == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pname = iport->iport_port->port_default_alias !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL ? iport->iport_port->port_default_alias : NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_port->port_sym_port_name = pname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pname == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto check_state_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctop = NS_RSPN_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_DO_RSNN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctop = NS_RSNN_NN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case LI_STATE_MAX:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_event(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_I_EVENT_LINK_INIT_DONE, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (elsop != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fct_create_solels(iport->iport_port, NULL, implicit,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte elsop, wkdid, fct_link_init_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ctop != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fct_create_solct(iport->iport_port, NULL, ctop,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_link_init_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state |= LI_STATE_FLAG_CMD_WAITING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(iport->iport_port, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handles both solicited and unsolicited elses. Can be called inside
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_els(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = (fct_i_cmd_t *)cmd->cmd_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t cmd_slot;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = els->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags |= ICMD_KNOWN_TO_FCA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Posting %ssol ELS %x (%s) rp_id=%x"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " lp_id=%x", (cmd->cmd_type == FCT_CMD_RCVD_ELS) ? "un" : "",
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan op, FCT_ELS_NAME(op), cmd->cmd_rportid,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan cmd->cmd_lportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestart_els_posting:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make sure local port is sane */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_state & S_LINK_ONLINE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "ELS %x not posted becasue"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "port state was %x", els->els_req_payload[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_LOCAL_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Weed out any bad initiators in case of N2N topology */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_type == FCT_CMD_RCVD_ELS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] == ELS_OP_PLOGI) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iport->iport_link_state == PORT_STATE_LINK_INIT_START) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iport->iport_link_info.port_topology == PORT_TOPOLOGY_PT_TO_PT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int state;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int killit = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state = iport->iport_li_state & LI_STATE_MASK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We dont allow remote port to plogi in N2N if we have not yet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * resolved the topology.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state <= LI_STATE_FINI_TOPOLOGY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte killit = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "port %x is trying to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "PLOGI in N2N topology, While we have not resolved"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " the topology. Dropping...", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (state <= LI_STATE_N2N_PLOGI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_lport_has_bigger_wwn(iport)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte killit = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "port %x is "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "trying to PLOGI in N2N topology, even "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "though it has smaller PWWN",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Remote port is assigning us a PORTID as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a part of PLOGI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.portid =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan cmd->cmd_lportid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (killit) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_LOCAL_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For all unsolicited ELSes that are not FLOGIs, our portid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has been established by now. Sometimes port IDs change due to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * link resets but remote ports may still send ELSes using the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * old IDs. Kill those right here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cmd->cmd_type == FCT_CMD_RCVD_ELS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] != ELS_OP_FLOGI)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_lportid != iport->iport_link_info.portid) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Rcvd %s with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "wrong lportid %x, expecting %x. Killing ELS.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_ELS_NAME(op), cmd->cmd_lportid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_link_info.portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_NOT_FOUND);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We always lookup by portid. port handles are too
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unreliable at this stage.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr(iport, cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (els->els_req_payload[0] == ELS_OP_PLOGI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* drop the lock while we do allocations */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp = fct_alloc(FCT_STRUCT_REMOTE_PORT,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fca_rp_private_size, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_ALLOC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = (fct_i_remote_port_t *)rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&irp->irp_lock, 0, RW_DRIVER, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_rp = rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_portid = cmd->cmd_rportid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_port = port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_id = cmd->cmd_rportid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_handle = FCT_HANDLE_NONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Grab port lock as writer since we are going
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to modify the local port struct.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make sure nobody created the struct except us */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_portid_to_portptr(iport, cmd->cmd_rportid)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Oh well, free it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(rp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_rp(iport, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_downgrade(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start over becasue we dropped the lock */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto start_els_posting;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A PLOGI is by default a logout of previous session */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_deregister_timer = ddi_get_lbolt() +
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan drv_usectohz(USEC_DEREG_RP_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_dereg_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_discovery_queue(iport, irp, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A PLOGI also invalidates any RSCNs related to this rp */
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&irp->irp_rscn_counter);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For everything else, we have (or be able to lookup) a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * valid port pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX Throw a logout to the initiator */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "ELS %x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "received from %x without a session",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[0], cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Sending ELS %x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "to %x without a session",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_payload[0], cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_NOT_LOGGED_IN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_rp = rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lets get a slot for this els
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(icmd->icmd_flags & ICMD_IMPLICIT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_slot = fct_alloc_cmd_slot(iport, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_slot == FCT_SLOT_EOL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This should not have happened */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan "ran out of xchg resources");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_NO_XCHG_RESOURCE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Tell the framework that fct_cmd_free() can decrement the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * irp_nonfcp_xchg_count variable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_IMPLICIT_CMD_HAS_RESOURCE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_nonfcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Grab the remote port lock while we modify the port state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we should not drop the fca port lock (as a reader) until we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * modify the remote port state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((op == ELS_OP_PLOGI) || (op == ELS_OP_PRLI) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (op == ELS_OP_LOGO) || (op == ELS_OP_PRLO) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (op == ELS_OP_TPRLO)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t rf = IRP_PRLI_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((op == ELS_OP_PLOGI) || (op == ELS_OP_LOGO)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rf |= IRP_PLOGI_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_PLOGI_DONE)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&iport->iport_nrps_login);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~rf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_SESSION_AFFECTING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_discovery_queue(iport, irp, icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Cleanup I/Os for a rport. ttc is a bit Mask of cmd types to clean.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * No locks held.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_trigger_rport_cleanup(fct_i_remote_port_t *irp, int ttc)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = irp->irp_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = rp->rp_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t total, cleaned, skipped, unhandled;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total = port->port_max_xchges - iport->iport_nslots_free;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cleaned = skipped = unhandled = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < port->port_max_xchges; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_cmd_slots[i].slot_cmd == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = iport->iport_cmd_slots[i].slot_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_IN_TRANSITION) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unhandled++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_CMD_COMPLETE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unhandled++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_rp != rp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte skipped++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type & ttc) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_FCP_XCHG)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_scsi_task_for_termination(cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_q_for_termination_lock_held(iport, icmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cleaned++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte skipped++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((cleaned + skipped) == total) && (unhandled == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX: handle this situation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Clean up trouble for irp"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %p, c/s/u/t = %d/%d/%d/%d", irp, cleaned, skipped,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan unhandled, total);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cleaned) && IS_WORKER_SLEEPING(iport))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&iport->iport_worker_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_dequeue_els(fct_i_remote_port_t *irp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = irp->irp_els_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_els_list = icmd->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_IN_IRP_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_register_remote_port(fct_local_port_t *port, fct_remote_port_t *rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport = (fct_i_local_port_t *)port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = (fct_i_remote_port_t *)rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = port->port_register_remote_port(port, rp, cmd)) !=
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_SUCCESS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rp->rp_handle != FCT_HANDLE_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rp->rp_handle >= port->port_max_logins) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_register_remote_port: FCA "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "returned a handle (%d) for portid %x which is "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "out of range (max logins = %d)", rp->rp_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_id, port->port_max_logins);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto hba_fatal_err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_rp_slots[rp->rp_handle] != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iport->iport_rp_slots[rp->rp_handle] != irp)) {
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan fct_i_remote_port_t *t_irp =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan iport->iport_rp_slots[rp->rp_handle];
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan "fct_register_remote_port: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "FCA returned a handle %d for portid %x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "which was already in use for a different "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "portid (%x)", rp->rp_handle, rp->rp_id,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan t_irp->irp_rp->rp_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto hba_fatal_err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Pick a handle for this port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < port->port_max_logins; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rp_slots[i] == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i == port->port_max_logins) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This is really pushing it. */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan "fct_register_remote_port "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Cannot register portid %x because all the "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "handles are used up", rp->rp_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto hba_fatal_err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_handle = i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* By this time rport_handle is valid */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_HANDLE_OPENED) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_slots[rp->rp_handle] = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_HANDLE_OPENED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
640c1670a105457bb0040e8e11037b53ab6ebcfaJosef 'Jeff' Sipek atomic_inc_64(&iport->iport_last_change);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_remote_port_event(port, ESC_SUNFC_TARGET_ADD,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_pwwn, rp->rp_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteregister_rp_done:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortehba_fatal_err:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * XXX Throw HBA fatal error event
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_deregister_remote_port(fct_local_port_t *port, fct_remote_port_t *rp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret = FCT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = PORT_TO_IPORT(port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = RP_TO_IRP(rp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_snn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(irp->irp_snn, strlen(irp->irp_snn) + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_snn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_spn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(irp->irp_spn, strlen(irp->irp_spn) + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_spn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = port->port_deregister_remote_port(port, rp)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_HANDLE_OPENED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_HANDLE_OPENED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rp_slots[rp->rp_handle] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
640c1670a105457bb0040e8e11037b53ab6ebcfaJosef 'Jeff' Sipek atomic_inc_64(&iport->iport_last_change);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_log_remote_port_event(port, ESC_SUNFC_TARGET_REMOVE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_pwwn, rp->rp_id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FCT_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_status_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_send_accrjt(fct_cmd_t *cmd, uint8_t accrjt, uint8_t reason, uint8_t expl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = (fct_local_port_t *)cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size = els->els_resp_alloc_size = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)kmem_zalloc(8, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[0] = accrjt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (accrjt == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[5] = reason;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[6] = expl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (port->port_send_cmd_response(cmd, 0));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_walk_discovery_queue(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t **pirp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *prev_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t suggested_action = DISC_ACTION_NO_WORK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_dereg_list = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_cur_item = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (pirp = &iport->iport_rpwe_head; *pirp != NULL; ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = *pirp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t ret = DISC_ACTION_NO_WORK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_deregister = 0;
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan int irp_deregister_timer = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_els_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_els(iport, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan irp_deregister_timer = irp->irp_deregister_timer;
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan if (irp_deregister_timer) {
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan if (ddi_get_lbolt() >= irp_deregister_timer) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_deregister = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= DISC_ACTION_DELAY_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_els_list == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_els_list == NULL) {
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan if (!irp_deregister_timer ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (do_deregister &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !irp->irp_sa_elses_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !irp->irp_nsa_elses_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !irp->irp_fcp_xchg_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !irp->irp_nonfcp_xchg_count)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* dequeue irp from discovery queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan ~IRP_IN_DISCOVERY_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *pirp = irp->irp_discovery_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_rpwe_head == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rpwe_tail = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (irp == iport->iport_rpwe_tail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_rpwe_tail =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan prev_irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_discovery_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_deregister) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_deque_rp(iport, irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* queue irp for deregister */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_next = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!irp_dereg_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_dereg_list =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item->irp_next =
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp = *pirp) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for another scan until
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * deregister timeout
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When we dropped the lock,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * something went in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= DISC_ACTION_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pirp = &(irp->irp_discovery_next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev_irp = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* do deregister */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp_dereg_list) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp_next_item;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* drop the lock */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (irp_cur_item = irp_dereg_list; irp_cur_item != NULL; ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_next_item = irp_cur_item->irp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_deregister_remote_port(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item->irp_rp) == FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(irp_cur_item->irp_rp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (++irp_cur_item->irp_dereg_count >= 5) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item->irp_deregister_timer = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item->irp_dereg_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It looks like we can't deregister it in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * normal way, so we have to use extrem way
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_walk_discovery_queue: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "iport-%p, can't deregister irp-%p after "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "trying 5 times", (void *)iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)irp_cur_item);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= DISC_ACTION_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* grab the iport_lock */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* recover */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item->irp_deregister_timer =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ddi_get_lbolt() +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(USEC_DEREG_RP_INTERVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_discovery_queue(iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_rp(iport, irp_cur_item);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte suggested_action |= DISC_ACTION_DELAY_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp_cur_item = irp_next_item;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (suggested_action);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_plogi(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cmd_type = cmd->cmd_type;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t icmd_flags = icmd->icmd_flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t end_time;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(rport__login__start,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd_type != FCT_CMD_RCVD_ELS));
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Drain I/Os */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_nonfcp_xchg_count + irp->irp_fcp_xchg_count) > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Trigger cleanup if necessary */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_SESSION_CLEANUP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling PLOGI rp_id"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x. Triggering cleanup", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Cleanup everything except elses */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_trigger_rport_cleanup(irp, ~(cmd->cmd_type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan IRP_SESSION_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: handle this */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* EMPTY */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_time = icmd->icmd_start_time +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(USEC_ELS_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() > end_time) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_process_plogi: unable to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "clean up I/O. iport-%p, icmd-%p", (void *)iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() & 0x7f) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " PLOGI rp_id %x, waiting for cmds to"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " drain", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SESSION_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Session can only be terminated after all the I/Os have drained */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_SCSI_SESSION_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_deregister_scsi_session(iport->iport_port->port_lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size = els->els_req_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_resp_payload = (uint8_t *)kmem_zalloc(
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan els->els_resp_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_alloc_size = els->els_resp_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(els->els_req_payload, p, els->els_resp_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0] = ELS_OP_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(p+20, rp->rp_pwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(p+28, rp->rp_nwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_pwwn, p+20, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_nwwn, p+28, 8);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_wwn_to_str(rp->rp_pwwn_str, rp->rp_pwwn);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_wwn_to_str(rp->rp_nwwn_str, rp->rp_nwwn);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_wwn_to_str(port->port_pwwn_str, port->port_pwwn);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_wwn_to_str(port->port_nwwn_str, port->port_nwwn);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_wwn_to_devid_desc((scsi_devid_desc_t *)irp->irp_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_pwwn, PROTOCOL_FIBRE_CHANNEL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_register_remote_port(port, rp, cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret == FCT_SUCCESS) && !(icmd->icmd_flags & ICMD_IMPLICIT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->port_send_cmd_response(cmd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret == FCT_SUCCESS) && IPORT_IN_NS_TOPO(iport) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !FC_WELL_KNOWN_ADDR(irp->irp_portid)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *ct_cmd = fct_create_solct(port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp, NS_GSNN_NN, fct_gsnn_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct_cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(port, ct_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct_cmd = fct_create_solct(port, rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_GSPN_ID, fct_gspn_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(port, ct_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct_cmd = fct_create_solct(port, rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_GCS_ID, fct_gcs_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(port, ct_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct_cmd = fct_create_solct(port, rp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_GFT_ID, fct_gft_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct_cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(port, ct_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The reason we set this flag is to prevent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * killing a PRLI while we have not yet processed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a response to PLOGI. Because the initiator
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will send a PRLI as soon as it responds to PLOGI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check fct_process_els() for more info.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan IRP_SOL_PLOGI_IN_PROGRESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->port_send_cmd(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan ~IRP_SOL_PLOGI_IN_PROGRESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_PLOGI_DONE);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&iport->iport_nrps_login);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_deregister_timer)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_deregister_timer = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd_flags & ICMD_IMPLICIT) {
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_5(rport__login__end,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd_type != FCT_CMD_RCVD_ELS),
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, FCT_SUCCESS);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0] = ELS_OP_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd->cmd_comp_status = FCT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_send_cmd_done(cmd, FCT_SUCCESS, FCT_IOF_FCA_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_5(rport__login__end,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd_type != FCT_CMD_RCVD_ELS),
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, ret);
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Do not touch cmd here as it may have been freed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint8_t fct_prli_temp[] = { 0x20, 0x10, 0, 0x14, 8, 0, 0x20, 0, 0, 0, 0, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, 0, 0, 0 };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_prli(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_scsi_session_t *ses = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t end_time;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We dont support solicited PRLIs yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_type == FCT_CMD_RCVD_ELS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_SOL_PLOGI_IN_PROGRESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dont process the PRLI yet. Let the framework process the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * PLOGI completion 1st. This should be very quick because
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the reason we got the PRLI is because the initiator
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * has responded to PLOGI already.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: Probably need a timeout here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The caller has made sure that login is done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make sure the process is fcp in this case */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((els->els_req_size != 20) || (bcmp(els->els_req_payload,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan fct_prli_temp, 16))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (els->els_req_payload[4] != 0x08)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "PRLI received from"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x for unknown FC-4 type %x", cmd->cmd_rportid,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan els->els_req_payload[4]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Rejecting PRLI from %x "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pld sz %d, prli_flags %x", cmd->cmd_rportid,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_req_size, els->els_req_payload[6]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(cmd, ELS_OP_LSRJT, 3, 0x2c);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto prli_end;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_fcp_xchg_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Trigger cleanup if necessary */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_FCP_CLEANUP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling PRLI from"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x. Triggering cleanup", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_trigger_rport_cleanup(irp, FCT_CMD_FCP_XCHG)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_FCP_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: handle this */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* EMPTY */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_time = icmd->icmd_start_time +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(USEC_ELS_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() > end_time) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_process_prli: unable to clean "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "up I/O. iport-%p, icmd-%p", (void *)iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() & 0x7f) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " PRLI from %x, waiting for cmds to"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " drain", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_FCP_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Session can only be terminated after all the I/Os have drained */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_SCSI_SESSION_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_deregister_scsi_session(iport->iport_port->port_lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* All good, lets start a session */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ses = (stmf_scsi_session_t *)stmf_alloc(STMF_STRUCT_SCSI_SESSION, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ses) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ses->ss_port_private = irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ses->ss_rport_id = (scsi_devid_desc_t *)irp->irp_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ses->ss_lport = port->port_lport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_register_scsi_session(port->port_lport, ses) !=
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan STMF_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(ses);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ses = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = ses;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session->ss_rport_alias = irp->irp_snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The reason IRP_SCSI_SESSION_STARTED is different
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from IRP_PRLI_DONE is that we clear IRP_PRLI_DONE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inside interrupt context. We dont want to deregister
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the session from an interrupt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ses == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fail PRLI */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(cmd, ELS_OP_LSRJT, 3, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* accept PRLI */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)kmem_zalloc(20, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(fct_prli_temp, els->els_resp_payload, 20);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[0] = 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[6] = 0x21;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX the two bytes below need to set as per capabilities */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[18] = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload[19] = 0x12;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size = els->els_resp_alloc_size = 20;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = port->port_send_cmd_response(cmd, 0)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_deregister_scsi_session(port->port_lport, ses);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Mark that PRLI is done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_PRLI_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteprli_end:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_logo(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t end_time;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(rport__logout__start,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd->cmd_type != FCT_CMD_RCVD_ELS));
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Drain I/Os */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_nonfcp_xchg_count + irp->irp_fcp_xchg_count) > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Trigger cleanup if necessary */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_SESSION_CLEANUP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling LOGO rp_id"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x. Triggering cleanup", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Cleanup everything except elses */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_trigger_rport_cleanup(irp, ~(cmd->cmd_type))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan IRP_SESSION_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: need more handling */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_time = icmd->icmd_start_time +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(USEC_ELS_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() > end_time) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_process_logo: unable to clean "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "up I/O. iport-%p, icmd-%p", (void *)iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() & 0x7f) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " LOGO rp_id %x, waiting for cmds to"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " drain", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SESSION_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Session can only be terminated after all the I/Os have drained */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_SCSI_SESSION_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_deregister_scsi_session(iport->iport_port->port_lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* don't send response if this is an implicit logout cmd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(icmd->icmd_flags & ICMD_IMPLICIT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(cmd, ELS_OP_ACC, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->port_send_cmd(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(rport__logout__end,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd->cmd_type != FCT_CMD_RCVD_ELS));
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer DTRACE_FC_4(rport__logout__end,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_cmd_t, cmd,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_local_port_t, port,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer fct_i_remote_port_t, irp,
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer int, (cmd->cmd_type != FCT_CMD_RCVD_ELS));
d8c54e3d070f57cc1b4d6c8262f0868219c8ce7cSam Cramer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_deregister_timer = ddi_get_lbolt() +
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan drv_usectohz(USEC_DEREG_RP_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_dereg_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Do not touch cmd here as it may have been freed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(irp->irp_flags & IRP_IN_DISCOVERY_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_prlo(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t end_time;
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan char info[FCT_INFO_LEN];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We do not support solicited PRLOs yet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_type == FCT_CMD_RCVD_ELS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Drain I/Os */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_fcp_xchg_count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Trigger cleanup if necessary */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((irp->irp_flags & IRP_FCP_CLEANUP) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling LOGO from"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " %x. Triggering cleanup", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Cleanup everything except elses */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_trigger_rport_cleanup(irp, FCT_CMD_FCP_XCHG)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan IRP_FCP_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: need more handling */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_time = icmd->icmd_start_time +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte drv_usectohz(USEC_ELS_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() > end_time) {
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan (void) snprintf(info, sizeof (info),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_process_prlo: unable to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "clean up I/O. iport-%p, icmd-%p", (void *)iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_port_shutdown(iport->iport_port,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_RFLAG_FATAL_ERROR | STMF_RFLAG_RESET, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ddi_get_lbolt() & 0x7f) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "handling"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " PRLO from %x, waiting for cmds to"
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan " drain", cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_FCP_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Session can only be terminated after all the I/Os have drained */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_SCSI_SESSION_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_deregister_scsi_session(iport->iport_port->port_lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_free(irp->irp_session);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_session = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SCSI_SESSION_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(cmd, ELS_OP_ACC, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_rcvd_adisc(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_remote_port_t *rp = cmd->cmd_rp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = cmd->cmd_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = (fct_i_local_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan port->port_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = (fct_els_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan cmd->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = (fct_i_remote_port_t *)
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan rp->rp_fct_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *q;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Validate the adisc request */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q = (uint32_t *)p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((els->els_req_size != 28) || (bcmp(rp->rp_pwwn, p + 8, 8)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (bcmp(rp->rp_nwwn, p + 16, 8))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(cmd, ELS_OP_LSRJT, 3, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rp->rp_hard_address = BE_32(q[1]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_size = els->els_resp_alloc_size = 28;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els->els_resp_payload = (uint8_t *)kmem_zalloc(28, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(p, els->els_resp_payload, 28);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = els->els_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q = (uint32_t *)p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p[0] = ELS_OP_ACC;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q[1] = BE_32(port->port_hard_address);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_pwwn, p + 8, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(port->port_nwwn, p + 16, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte q[6] = BE_32(iport->iport_link_info.portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = port->port_send_cmd_response(cmd, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_unknown_els(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret = FCT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(icmd->icmd_cmd->cmd_type == FCT_CMD_RCVD_ELS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(ICMD_TO_IRP(icmd));
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&ICMD_TO_IRP(icmd)->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = ICMD_TO_ELS(icmd)->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Rejecting unknown unsol els %x (%s)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op, FCT_ELS_NAME(op));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(icmd->icmd_cmd, ELS_OP_LSRJT, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(icmd->icmd_cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_rscn(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret = FCT_FAILURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *rscn_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t rscn_req_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(ICMD_TO_IRP(icmd));
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&ICMD_TO_IRP(icmd)->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cmd->cmd_type == FCT_CMD_RCVD_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = ICMD_TO_ELS(icmd)->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Accepting RSCN %x (%s)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op, FCT_ELS_NAME(op));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_req_size = ICMD_TO_ELS(icmd)->els_req_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_req_payload = kmem_alloc(rscn_req_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ICMD_TO_ELS(icmd)->els_req_payload, rscn_req_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_req_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = fct_send_accrjt(icmd->icmd_cmd, ELS_OP_ACC, 1, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(icmd->icmd_cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_rscn_options & RSCN_OPTION_VERIFY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_rscn_verify(iport, rscn_req_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rscn_req_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(rscn_req_payload, rscn_req_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedisc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_process_els(fct_i_local_port_t *iport, fct_i_remote_port_t *irp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *cmd_to_abort = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t **ppcmd, *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int dq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disc_action_t ret = DISC_ACTION_NO_WORK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do some cleanup based on the following.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - We can only have one session affecting els pending.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If any session affecting els is pending no other els is allowed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If PLOGI is not done, nothing except PLOGI or LOGO is allowed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: If port is down the cleanup is done outside of this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: There is a side effect, if a sa ELS (non PLOGI) is received
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * while a PLOGI is pending, it will kill itself and the PLOGI.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which is probably ok.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppcmd = &irp->irp_els_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((*ppcmd) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int special_prli_cond = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dq = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els = (fct_els_t *)((*ppcmd)->icmd_cmd)->cmd_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((*ppcmd)->icmd_cmd->cmd_type == FCT_CMD_RCVD_ELS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] == ELS_OP_PRLI) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (irp->irp_flags & IRP_SOL_PLOGI_IN_PROGRESS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The initiator sent a PRLI right after responding
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to PLOGI and we have not yet finished processing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the PLOGI completion. We should not kill the PRLI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as the initiator may not retry it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte special_prli_cond = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*ppcmd)->icmd_flags & ICMD_BEING_ABORTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dq = 1;
d6b3018d1023e158e4d4f1315056f98b55c6f590Sumit Gupta } else if (irp->irp_sa_elses_count > 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dq = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This els might have set the CLEANUP flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SESSION_CLEANUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Killing ELS %x cond 1",
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan els->els_req_payload[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (irp->irp_sa_elses_count &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((*ppcmd)->icmd_flags & ICMD_SESSION_AFFECTING) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Killing ELS %x cond 2",
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan els->els_req_payload[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dq = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (((irp->irp_flags & IRP_PLOGI_DONE) == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] != ELS_OP_PLOGI) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] != ELS_OP_LOGO) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (special_prli_cond == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Killing ELS %x cond 3",
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan els->els_req_payload[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dq = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dq) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *c = (*ppcmd)->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*ppcmd)->icmd_flags & ICMD_SESSION_AFFECTING)
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_sa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*ppcmd)->icmd_next = cmd_to_abort;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_to_abort = *ppcmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ppcmd = c;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppcmd = &((*ppcmd)->icmd_next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (cmd_to_abort) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *c = cmd_to_abort->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&cmd_to_abort->icmd_flags, ~ICMD_IN_IRP_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd_to_abort->icmd_cmd,
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan FCT_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd_to_abort = c;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pick from the top of the queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = irp->irp_els_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The cleanup took care of everything.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = icmd->icmd_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte els = ICMD_TO_ELS(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op = els->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((icmd->icmd_flags & ICMD_ELS_PROCESSING_STARTED) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Processing %ssol ELS %x (%s) "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rp_id=%x", (cmd->cmd_type == FCT_CMD_RCVD_ELS) ? "un" : "",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte op, FCT_ELS_NAME(op), cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_ELS_PROCESSING_STARTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (op == ELS_OP_PLOGI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_plogi(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (op == ELS_OP_PRLI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_prli(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (op == ELS_OP_LOGO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_logo(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((op == ELS_OP_PRLO) || (op == ELS_OP_TPRLO)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_prlo(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = iport->iport_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_dequeue_els(irp);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_16(&irp->irp_nsa_elses_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((s = port->port_send_cmd(cmd)) != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Solicited els "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "transport failed, ret = %llx", s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (op == ELS_OP_ADISC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret |= fct_process_rcvd_adisc(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (op == ELS_OP_RSCN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_process_rscn(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fct_process_unknown_els(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This if condition will be false if a sa ELS trigged a cleanup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and set the ret = DISC_ACTION_DELAY_RESCAN. In that case we should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * keep it that way.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == DISC_ACTION_NO_WORK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since we dropped the lock, we will force a rescan. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * only exception is if someone returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DISC_ACTION_DELAY_RESCAN, in which case that should be the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = DISC_ACTION_RESCAN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_sol_els_completion(fct_i_local_port_t *iport, fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_els_t *els = ICMD_TO_ELS(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t op = els->els_req_payload[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cmd->cmd_rp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = ICMD_TO_IRP(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cmd->cmd_rp &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (icmd->icmd_cmd->cmd_comp_status == FCT_SUCCESS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (els->els_req_payload[0] == ELS_OP_PLOGI)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(els->els_resp_payload + 20, irp->irp_rp->rp_pwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(els->els_resp_payload + 28, irp->irp_rp->rp_nwwn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_wwn_to_devid_desc((scsi_devid_desc_t *)irp->irp_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_rp->rp_pwwn, PROTOCOL_FIBRE_CHANNEL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&irp->irp_flags, IRP_PLOGI_DONE);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&iport->iport_nrps_login);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_deregister_timer) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_deregister_timer = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_dereg_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp && (els->els_req_payload[0] == ELS_OP_PLOGI)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&irp->irp_flags, ~IRP_SOL_PLOGI_IN_PROGRESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_CMD_COMPLETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "Sol ELS %x (%s) completed with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "status %llx, did/%x", op, FCT_ELS_NAME(op),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cmd->cmd_comp_status, icmd->icmd_cmd->cmd_rportid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic disc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_check_cmdlist(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_to_release, ndx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t total, max_active;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(MUTEX_HELD(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total = iport->iport_total_alloced_ncmds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_active = iport->iport_max_active_ncmds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (total <= max_active)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_NO_WORK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Everytime, we release half of the difference
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_to_release = (total + 1 - max_active) / 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ndx = 0; ndx < num_to_release; ndx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd = iport->iport_cached_cmdlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_cached_cmd_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_cmdlist = icmd->icmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_cached_ncmds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_cached_cmd_lock);
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&iport->iport_total_alloced_ncmds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_free(icmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The efficiency of handling solicited commands is very low here. But
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fortunately, we seldom send solicited commands. So it will not hurt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the system performance much.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic disc_action_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_check_solcmd_queue(fct_i_local_port_t *iport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *prev_icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *next_icmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(mutex_owned(&iport->iport_worker_lock));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (icmd = iport->iport_solcmd_queue; icmd; icmd = next_icmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(icmd->icmd_flags | ICMD_IN_SOLCMD_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_icmd = icmd->icmd_solcmd_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_flags & ICMD_SOLCMD_NEW) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This solicited cmd is new.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dispatch ELSes to discovery queue to make use of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * existent framework.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_flags &= ~ICMD_SOLCMD_NEW;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_els(icmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_handle_solct(icmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (icmd->icmd_flags & ICMD_CMD_COMPLETE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To make fct_check_solcmd simple and flexible,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need only call callback to finish post-handling.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cb) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mutex ???
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cb(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release resources for this solicited cmd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iport->iport_solcmd_queue == icmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_solcmd_queue = next_icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan prev_icmd = iport->iport_solcmd_queue;
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan while (prev_icmd->icmd_solcmd_next != icmd) {
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan prev_icmd = prev_icmd->icmd_solcmd_next;
590ebdb02417ee80bf5da3a617dadf2469fa3b7eallan }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prev_icmd->icmd_solcmd_next = next_icmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cb = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_free(icmd->icmd_cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This solicited cmd is still ongoing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need check if it's time to abort this cmd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((icmd->icmd_start_time + drv_usectohz(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte USEC_SOL_TIMEOUT)) < ddi_get_lbolt()) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(icmd->icmd_flags & ICMD_BEING_ABORTED)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_q_for_termination_lock_held(iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd, FCT_ABORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (DISC_ACTION_DELAY_RESCAN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_handle_solct(fct_cmd_t *cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_status_t ret = FCT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_cmd_t *icmd = CMD_TO_ICMD(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = ICMD_TO_IRP(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(cmd->cmd_type == FCT_CMD_SOL_CT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let's make sure local port is sane
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iport->iport_link_state & S_LINK_ONLINE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "fct_transport_solct: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "solcmd-%p transport failed, becasue port state was %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd, iport->iport_link_state);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_LOCAL_PORT_OFFLINE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let's make sure we have plogi-ed to name server
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&irp->irp_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(irp->irp_flags & IRP_PLOGI_DONE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "fct_transport_solct: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Must login to name server first - cmd-%p", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_NOT_LOGGED_IN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Let's get a slot for this solcmd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_alloc_cmd_slot(iport, cmd) == FCT_SLOT_EOL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "fct_transport_solcmd: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "ran out of xchg resources - cmd-%p", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, FCT_NO_XCHG_RESOURCE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fct_netbuf_to_value(ICMD_TO_CT(icmd)->ct_req_payload + 8, 2) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NS_GID_PN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_lookup_irp_by_portwwn(iport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_req_payload + 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&query_irp->irp_flags, ~IRP_RSCN_QUEUED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&irp->irp_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_16(&irp->irp_nonfcp_xchg_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&icmd->icmd_flags, ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_start_time = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = iport->iport_port->port_send_cmd(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&icmd->icmd_flags, ~ICMD_KNOWN_TO_FCA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_queue_cmd_for_termination(cmd, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_logo_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!(icmd->icmd_flags & ICMD_IMPLICIT));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_ELS_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_logo_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "solicited LOGO is not accepted - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_gsnn_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int snlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *sn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gsnn_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GSNN is not accepted by NS - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&ICMD_TO_IPORT(icmd)->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_lookup_irp_by_nodewwn(ICMD_TO_IPORT(icmd),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_req_payload + 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!query_irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gsnn_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "can't get rp icmd-%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto exit_gsnn_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte snlen = ICMD_TO_CT(icmd)->ct_resp_payload[16];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp && snlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Release previous resource, then allocate needed resource
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sn = query_irp->irp_snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(sn, strlen(sn) + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_snn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sn = kmem_zalloc(snlen + 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(sn, (char *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_resp_payload + 17, snlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strlen(sn) != snlen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_gsnn_cb: %s, but len=%d", sn, snlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(sn, snlen + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sn = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Update symbolic node name
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_snn = sn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((query_irp->irp_flags & IRP_SCSI_SESSION_STARTED) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (query_irp->irp_session)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_session->ss_rport_alias =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_snn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gsnn_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "irp/%p, snlen/%d", query_irp, snlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteexit_gsnn_cb:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&ICMD_TO_IPORT(icmd)->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_link_init_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_state &= ~LI_STATE_FLAG_CMD_WAITING;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (icmd->icmd_cmd->cmd_comp_status != FCT_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias, "fct_link_init_cb: ELS-%x failed"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "comp_status- %llx", ICMD_TO_ELS(icmd)->els_req_payload[0],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte icmd->icmd_cmd->cmd_comp_status);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status = icmd->icmd_cmd->cmd_comp_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (icmd->icmd_cmd->cmd_type == FCT_CMD_SOL_ELS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_ELS_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_link_init_cb: ELS-%x is rejected",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_ELS(icmd)->els_req_payload[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status = FCT_REJECT_STATUS(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_ELS(icmd)->els_resp_payload[1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_ELS(icmd)->els_resp_payload[2]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status = FCT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(icmd->icmd_cmd->cmd_type == FCT_CMD_SOL_CT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(iport->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fct_link_init_cb: CT-%02x%02x is rejected",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_req_payload[8],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_req_payload[9]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status = FCT_REJECT_STATUS(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_resp_payload[8],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_resp_payload[9]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iport->iport_li_comp_status = FCT_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_gcs_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = ICMD_TO_CT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t query_portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gcs_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GCS_ID is not accepted by NS - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp = ct->ct_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = ct->ct_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_portid = (req[17] << 16) | (req[18] << 8) | req[19];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_portid_to_portptr(iport, query_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_cos = (resp[16] << 27) | (resp[17] << 18) |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (resp[18] << 8) | resp[19];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_gft_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = ICMD_TO_CT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t query_portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gft_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GFT_ID is not accepted by NS - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp = ct->ct_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = ct->ct_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_portid = (req[17] << 16) | (req[18] << 8) | req[19];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_portid_to_portptr(iport, query_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy(query_irp->irp_fc4types, resp + 16, 32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_gid_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t nsportid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int do_logo = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&ICMD_TO_IPORT(icmd)->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_lookup_irp_by_portwwn(ICMD_TO_IPORT(icmd),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_req_payload + 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!query_irp || (query_irp &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (PTR2INT(icmd->icmd_cb_private, uint32_t) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_rscn_counter))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gid_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "new RSCN arrived - query_irp/%p, private-%x", query_irp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte PTR2INT(icmd->icmd_cb_private, uint32_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto exit_gid_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((query_irp->irp_flags & IRP_RSCN_QUEUED) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!(query_irp->irp_flags & IRP_PLOGI_DONE))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gid_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "not proper irp_flags - query_irp/%p", query_irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto exit_gid_cb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if it has disappeared
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gid_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GPN_ID is not accepted by NS - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_logo = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if its portid has changed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsportid = fct_netbuf_to_value(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ICMD_TO_CT(icmd)->ct_resp_payload + 17, 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nsportid != query_irp->irp_rp->rp_id) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "portid has changed - query_irp/%p", query_irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_logo = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_logo) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = fct_create_solels(ICMD_TO_PORT(icmd),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_rp, 1, ELS_OP_LOGO, 0, fct_logo_cb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_implicit_logo(cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&ICMD_TO_IPORT(icmd)->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteexit_gid_cb:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&ICMD_TO_IPORT(icmd)->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_gspn_cb(fct_i_cmd_t *icmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_sol_ct_t *ct = ICMD_TO_CT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *query_irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t query_portid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t spnlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!FCT_IS_CT_ACC(icmd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_gspn_cb: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "GSPN_ID is not accepted by NS - icmd/%p", icmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp = ct->ct_resp_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = ct->ct_req_payload;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_portid = (req[17] << 16) | (req[18] << 8) | req[19];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&iport->iport_worker_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp = fct_portid_to_portptr(iport, query_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte spnlen = resp[16];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (spnlen > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (query_irp->irp_spn) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(query_irp->irp_spn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen(query_irp->irp_spn) + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte query_irp->irp_spn = kmem_zalloc(spnlen + 1, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy(query_irp->irp_spn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (char *)resp + 17, spnlen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c946faca5d4627284fb79c6b04e652b471034495allanvoid
c946faca5d4627284fb79c6b04e652b471034495allanfct_rls_cb(fct_i_cmd_t *icmd)
c946faca5d4627284fb79c6b04e652b471034495allan{
c946faca5d4627284fb79c6b04e652b471034495allan fct_els_t *els = ICMD_TO_ELS(icmd);
c946faca5d4627284fb79c6b04e652b471034495allan uint8_t *resp;
c946faca5d4627284fb79c6b04e652b471034495allan fct_rls_cb_data_t *rls_cb_data = NULL;
c946faca5d4627284fb79c6b04e652b471034495allan fct_port_link_status_t *rls_resp;
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_local_port_t *iport = ICMD_TO_IPORT(icmd);
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan rls_cb_data = icmd->icmd_cb_private;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (!FCT_IS_ELS_ACC(icmd)) {
c946faca5d4627284fb79c6b04e652b471034495allan stmf_trace(ICMD_TO_IPORT(icmd)->iport_alias, "fct_rls_cb: "
c946faca5d4627284fb79c6b04e652b471034495allan "solicited RLS is not accepted - icmd/%p", icmd);
c946faca5d4627284fb79c6b04e652b471034495allan if (rls_cb_data) {
c946faca5d4627284fb79c6b04e652b471034495allan rls_cb_data->fct_els_res = FCT_FAILURE;
c946faca5d4627284fb79c6b04e652b471034495allan sema_v(&iport->iport_rls_sema);
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan return;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan if (!rls_cb_data) {
c946faca5d4627284fb79c6b04e652b471034495allan sema_v(&iport->iport_rls_sema);
c946faca5d4627284fb79c6b04e652b471034495allan return;
c946faca5d4627284fb79c6b04e652b471034495allan }
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan resp = els->els_resp_payload;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan rls_cb_data = icmd->icmd_cb_private;
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan /* Get the response and store it somewhere */
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp = (fct_port_link_status_t *)rls_cb_data->fct_link_status;
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->LinkFailureCount = BE_32(*((uint32_t *)(resp + 4)));
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->LossOfSyncCount = BE_32(*((uint32_t *)(resp + 8)));
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->LossOfSignalsCount = BE_32(*((uint32_t *)(resp + 12)));
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->PrimitiveSeqProtocolErrorCount =
c946faca5d4627284fb79c6b04e652b471034495allan BE_32(*((uint32_t *)(resp + 16)));
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->InvalidTransmissionWordCount =
c946faca5d4627284fb79c6b04e652b471034495allan BE_32(*((uint32_t *)(resp + 20)));
c946faca5d4627284fb79c6b04e652b471034495allan rls_resp->InvalidCRCCount = BE_32(*((uint32_t *)(resp + 24)));
c946faca5d4627284fb79c6b04e652b471034495allan
c946faca5d4627284fb79c6b04e652b471034495allan rls_cb_data->fct_els_res = FCT_SUCCESS;
c946faca5d4627284fb79c6b04e652b471034495allan sema_v(&iport->iport_rls_sema);
c946faca5d4627284fb79c6b04e652b471034495allan icmd->icmd_cb_private = NULL;
c946faca5d4627284fb79c6b04e652b471034495allan}
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For lookup functions, we move locking up one level
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_i_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_lookup_irp_by_nodewwn(fct_i_local_port_t *iport, uint8_t *nodewwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int idx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (idx = 0; idx < FCT_HASH_TABLE_SIZE; idx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (irp = iport->iport_rp_tb[idx]; irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(irp->irp_rp->rp_nwwn, nodewwn, FC_WWN_LEN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_i_remote_port_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_lookup_irp_by_portwwn(fct_i_local_port_t *iport, uint8_t *portwwn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int idx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (idx = 0; idx < FCT_HASH_TABLE_SIZE; idx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (irp = iport->iport_rp_tb[idx]; irp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = irp->irp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(irp->irp_rp->rp_pwwn, portwwn, FC_WWN_LEN)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (irp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCT_VERIFY_RSCN() _NOTE(EMPTY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define FCT_VERIFY_RSCN() \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo { \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ct_cmd = fct_create_solct(port, irp->irp_rp, NS_GID_PN, \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_gid_cb); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ct_cmd) { \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cnt; \
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek cnt = atomic_inc_32_nv(&irp->irp_rscn_counter); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CMD_TO_ICMD(ct_cmd)->icmd_cb_private = \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte INT2PTR(cnt, void *); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp->irp_flags |= IRP_RSCN_QUEUED; \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_post_to_solcmd_queue(port, ct_cmd); \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} while (0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefct_rscn_verify(fct_i_local_port_t *iport, uint8_t *rscn_req_payload,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t rscn_req_size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int idx = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t page_format = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t page_portid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *page_buf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *last_page_buf = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_cmd_t *ct_cmd = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_local_port_t *port = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_i_remote_port_t *irp = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_buf = rscn_req_payload + 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte last_page_buf = rscn_req_payload +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fct_netbuf_to_value(rscn_req_payload + 2, 2) - 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte port = iport->iport_port;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; page_buf <= last_page_buf; page_buf += 4) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_format = 0x03 & page_buf[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_portid = fct_netbuf_to_value(page_buf + 1, 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c946faca5d4627284fb79c6b04e652b471034495allan DTRACE_FC_2(rscn__receive,
c946faca5d4627284fb79c6b04e652b471034495allan fct_i_local_port_t, iport,
c946faca5d4627284fb79c6b04e652b471034495allan int, page_portid);
c946faca5d4627284fb79c6b04e652b471034495allan
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iport->iport_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!page_format) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp = fct_portid_to_portptr(iport, page_portid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(irp && !(irp->irp_flags & IRP_RSCN_QUEUED))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; /* try next page */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_WELL_KNOWN_ADDR(irp->irp_portid) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(irp->irp_flags & IRP_PLOGI_DONE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; /* try next page */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_VERIFY_RSCN();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (idx = 0; idx < FCT_HASH_TABLE_SIZE; idx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (irp = iport->iport_rp_tb[idx];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte irp; irp = irp->irp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (FC_WELL_KNOWN_ADDR(irp->irp_portid))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; /* try next irp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(irp->irp_flags & IRP_PLOGI_DONE))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; /* try next irp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (irp->irp_flags & IRP_RSCN_QUEUED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; /* try next irp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!((0xFFFFFF << (page_format * 8)) &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (page_portid ^ irp->irp_portid))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte FCT_VERIFY_RSCN();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iport->iport_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}