discovery.c revision 4558d122136f151d62acbbc02ddb42df89a5ef66
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/byteorder.h>
#include <sys/stmf_ioctl.h>
#include "fct_impl.h"
#include "discovery.h"
"ABTX", "RCS", "RES", "RSS", "RSI", "ESTS",
"ESTC", "ADVC", "RTV", "RLS",
/* 0x10 */ "ECHO", "TEST", "RRQ", "REC", "SRR", 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x20 */ "PRLI", "PRLO", "SCN", "TPLS",
"TPRLO", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x50 */ "PDISC", "FDISC", "ADISC", "RNC", "FARP",
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x60 */ "FAN", "RSCN", "SCR", 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
/* 0x70 */ "LINIT", "LPC", "LSTS", 0, 0, 0, 0, 0,
"RNID", "RLIR", "LIRR", 0, 0, 0, 0, 0
};
extern uint32_t fct_rscn_options;
/*
* NOTE: if anybody drops the iport_worker_lock then they should not return
* DISC_ACTION_NO_WORK. Which also means, dont drop the lock if you have
* nothing to do. Or else return DISC_ACTION_RESCAN or DISC_ACTION_DELAY_RESCAN.
* But you cannot be infinitly returning those so have some logic to
* determine that there is nothing to do without dropping the lock.
*/
void
fct_port_worker(void *arg)
{
/* Discovery loop */
/*
* Local port events are of the highest prioriy
*/
if (iport->iport_event_head) {
}
/*
* We could post solicited ELSes to discovery queue.
* solicited CT will be processed inside fct_check_solcmd_queue
*/
if (iport->iport_solcmd_queue) {
}
/*
* All solicited and unsolicited ELS will be handled here
*/
if (iport->iport_rpwe_head) {
}
/*
* We only process it when there's no outstanding link init CMD
*/
}
/*
* We process cmd aborting in the end
*/
if (iport->iport_abort_queue) {
}
/*
*/
iport->iport_max_active_ncmds = 0;
}
}
if (suggested_action & DISC_ACTION_RESCAN) {
continue;
} else if (suggested_action & DISC_ACTION_DELAY_RESCAN) {
/*
* This is not very optimum as whoever returned
* DISC_ACTION_DELAY_RESCAN must have dropped the lock
* and more things might have queued up. But since
* we are only doing small delays, it only delays
* things by a few ms, which is okey.
*/
dl = short_delay;
} else {
dl = long_delay;
}
} else {
ddi_get_lbolt());
if (tmp_delay < 0) {
}
}
}
}
"Unknown", "Unknown", "Fabric Pt-to-Pt",
"Public Loop" };
void
{
} else {
}
if ((s == 0) || ((s & 0xf00) != 0) || ((s & (s - 1)) != 0)) {
speed[0] = '?';
} else if (s == PORT_SPEED_10G) {
speed[0] = '1';
speed[3] = 0;
} else {
speed[2] = 0;
}
}
/*
* discovery lock held.
* XXX: Implement command cleanup upon Link down.
* XXX: Implement a clean start and FC-GS registrations upon Link up.
*
* ================ Local Port State Machine ============
* <hba fatal> <Link up>---|
* | v
* | <Start>--->[LINK_DOWN]--->[LINK_INIT_START]--->[LINK_INIT_DONE]
* | ^ ^ ^ | |
* | |---| | |--<Link down> |-| |---><Link Reset><--|
* | | | v | v
* |->[FATAL_CLEANING] [LINK_DOWN_CLEANING]--->[LINK_UP_CLEANING]
* ^
* |--<Link up>
* =======================================================
* An explicit port_online() is only allowed in LINK_DOWN state.
* An explicit port_offline() is only allowed in LINKDOWN and
* LINK_INIT_DONE state.
*/
{
int dqueue_and_free = 1;
int retry_implicit_logo = 0;
return (DISC_ACTION_NO_WORK);
}
/* Calculate new state */
else { /* This should not happen */
"Link up received when link state was"
}
if (!fct_local_port_cleanup_done(iport)) {
retry_implicit_logo = 1;
} else {
}
dqueue_and_free = 0;
} else {
if (iport->iport_link_state ==
} else if (iport->iport_link_state ==
} else { /* This should not have happened */
}
}
/* Link reset is only allowed when we are Online */
}
}
} else {
ASSERT(0);
}
if (new_bits & S_PORT_CLEANUP) {
(void) fct_implicitly_logo_all(iport, 0);
FCT_I_EVENT_CLEANUP_POLL, 0, 0);
}
if (retry_implicit_logo) {
}
if (new_bits & S_INIT_LINK) {
"port_get_link_info failed, ret %llx, forcing "
FCT_EVENT_LINK_DOWN, 0, 0);
} else {
iport->iport_login_retry = 0;
/* This will reset LI_STATE_FLAG_NO_LI_YET */
}
} else if (new_bits & S_RCVD_LINK_DOWN) {
}
if (in && dqueue_and_free) {
}
return (ret);
}
int
{
uint8_t *l, *r;
int i;
for (i = 0, wl = 0; i < 8; i++) {
wl <<= 8;
wl |= l[i];
}
for (i = 0, wr = 0; i < 8; i++) {
wr <<= 8;
wr |= r[i];
}
return (1);
}
return (0);
}
void
{
int force_link_down = 0;
int do_retry = 0;
if (iport->iport_login_retry == 0) {
} else {
}
}
if (IPORT_FLOGI_DONE(iport)) {
/* The unsolicited path finished it. */
goto done;
}
if (ret == FCT_NOT_FOUND) {
/* This is a private loop. There is no switch. */
goto done;
}
/*
* This is really an error. This means we cannot init the
* link. Lets force the link to go down.
*/
force_link_down = 1;
do_retry = 1;
} else {
force_link_down = 1;
}
} else if (ret == STMF_TIMEOUT) {
do_retry = 1;
} else if (ret != FCT_SUCCESS) {
force_link_down = 1;
}
if (do_retry) {
force_link_down = 1;
goto done;
}
if (force_link_down) {
"Forcing link down, ret=%llx login_retry=%d ret_op=%d "
goto done;
}
/* FLOGI succeeded. Update local port state */
}
done:
}
/*
* Called by FCAs to handle unsolicited FLOGIs.
*/
{
uint32_t t;
return (FCT_FAILURE);
}
return (FCT_FAILURE);
}
}
return (FCT_SUCCESS);
}
/*
* iport_li_state can only be changed here and local_event
*/
{
int implicit = 0;
int force_login = 0;
case LI_STATE_DO_FLOGI:
/* Is FLOGI even needed or already done ? */
(IPORT_FLOGI_DONE(iport))) {
iport->iport_li_state++;
goto check_state_again;
}
break;
case LI_STATE_FINI_TOPOLOGY:
if (li->port_topology !=
if (iport->iport_nrps) {
/*
* rehash it if change from fabric to
* none fabric, vice versa
*/
if ((li->port_topology ^
}
}
}
/* Skip next level if topo is not N2N */
} else {
iport->iport_li_state++;
iport->iport_login_retry = 0;
}
goto check_state_again;
case LI_STATE_N2N_PLOGI:
" to PLOGI to remote port in N2N "
" ret=%llx, forcing link down",
FCT_EVENT_LINK_DOWN, 0, 0);
}
}
}
/* Find out if we need to do PLOGI at all */
if (iport->iport_nrps_login) {
iport->iport_li_state++;
goto check_state_again;
}
(!fct_lport_has_bigger_wwn(iport))) {
/* Cant wait forever */
"not logging in, forcing from our side");
force_login = 1;
} else {
force_login = 0;
}
wkdid = 1;
implicit = 0;
} else {
}
break;
case LI_STATE_DO_FCLOGIN:
/*
* Fabric controller login failed. Just skip all
* the fabric controller related cmds.
*/
} else {
/*
* Good. Now lets go to next state
*/
iport->iport_li_state++;
}
goto check_state_again;
}
if (!IPORT_IN_NS_TOPO(iport)) {
goto check_state_again;
}
implicit = 1;
/*
* We want to come back in the same state and check its ret
* We can't modify the state here
*/
break;
case LI_STATE_DO_SCR:
elsop = ELS_OP_SCR;
/*
* We dont care about success of this state. Just go to
* next state upon completion.
*/
iport->iport_li_state++;
break;
case LI_STATE_DO_NSLOGIN:
} else {
iport->iport_li_state++;
}
goto check_state_again;
}
if (!IPORT_IN_NS_TOPO(iport)) {
goto check_state_again;
}
break;
/*
* CT state
*/
case LI_STATE_DO_RNN:
iport->iport_li_state++;
break;
case LI_STATE_DO_RCS:
iport->iport_li_state++;
break;
case LI_STATE_DO_RFT:
iport->iport_li_state++;
break;
case LI_STATE_DO_RSPN:
/*
* Check if we need skip the state
*/
}
iport->iport_li_state++;
goto check_state_again;
}
ctop = NS_RSPN_ID;
iport->iport_li_state++;
break;
case LI_STATE_DO_RSNN:
ctop = NS_RSNN_NN;
iport->iport_li_state++;
break;
case LI_STATE_MAX:
FCT_I_EVENT_LINK_INIT_DONE, 0, 0);
break;
default:
ASSERT(0);
}
if (elsop != 0) {
} else if (ctop != 0) {
}
if (cmd) {
}
return (ret);
}
/*
* Handles both solicited and unsolicited elses. Can be called inside
* interrupt context.
*/
void
{
}
cmd->cmd_lportid);
/* Make sure local port is sane */
return;
}
/* Weed out any bad initiators in case of N2N topology */
int state;
int killit = 0;
/*
* We dont allow remote port to plogi in N2N if we have not yet
* resolved the topology.
*/
if (state <= LI_STATE_FINI_TOPOLOGY) {
killit = 1;
"PLOGI in N2N topology, While we have not resolved"
} else if (state <= LI_STATE_N2N_PLOGI) {
if (fct_lport_has_bigger_wwn(iport)) {
killit = 1;
"trying to PLOGI in N2N topology, even "
"though it has smaller PWWN",
cmd->cmd_rportid);
} else {
/*
* Remote port is assigning us a PORTID as
* a part of PLOGI.
*/
}
}
if (killit) {
return;
}
}
/*
* For all unsolicited ELSes that are not FLOGIs, our portid
* has been established by now. Sometimes port IDs change due to
* link resets but remote ports may still send ELSes using the
* old IDs. Kill those right here.
*/
"wrong lportid %x, expecting %x. Killing ELS.",
return;
}
}
/*
* We always lookup by portid. port handles are too
* unreliable at this stage.
*/
/* drop the lock while we do allocations */
port->port_fca_rp_private_size, 0);
return;
}
/*
* Grab port lock as writer since we are going
* to modify the local port struct.
*/
/* Make sure nobody created the struct except us */
/* Oh well, free it */
} else {
}
/* Start over becasue we dropped the lock */
goto start_els_posting;
}
/* A PLOGI is by default a logout of previous session */
irp->irp_dereg_count = 0;
/* A PLOGI also invalidates any RSCNs related to this rp */
} else {
/*
* For everything else, we have (or be able to lookup) a
* valid port pointer.
*/
/* XXX Throw a logout to the initiator */
"received from %x without a session",
} else {
"to %x without a session",
}
return;
}
}
/*
* Lets get a slot for this els
*/
if (cmd_slot == FCT_SLOT_EOL) {
/* This should not have happened */
"ran out of xchg resources");
return;
}
} else {
/*
* Tell the framework that fct_cmd_free() can decrement the
* irp_nonfcp_xchg_count variable.
*/
}
/*
* Grab the remote port lock while we modify the port state.
* we should not drop the fca port lock (as a reader) until we
* modify the remote port state.
*/
(op == ELS_OP_TPRLO)) {
rf |= IRP_PLOGI_DONE;
}
} else {
}
}
/*
* No locks held.
*/
int
{
int i;
int ret;
for (i = 0; i < port->port_max_xchges; i++) {
continue;
unhandled++;
continue;
}
unhandled++;
continue;
}
skipped++;
continue;
}
else
cleaned++;
} else {
skipped++;
}
}
ret = 1;
} else {
/*
* XXX: handle this situation.
*/
ret = 0;
}
return (ret);
}
void
{
}
{
int i;
char info[FCT_INFO_LEN];
return (ret);
"fct_register_remote_port: FCA "
"returned a handle (%d) for portid %x which is "
goto hba_fatal_err;
}
"fct_register_remote_port: "
"FCA returned a handle %d for portid %x "
"which was already in use for a different "
goto hba_fatal_err;
}
} else {
/* Pick a handle for this port */
for (i = 0; i < port->port_max_logins; i++) {
break;
}
}
if (i == port->port_max_logins) {
/* This is really pushing it. */
"fct_register_remote_port "
"Cannot register portid %x because all the "
goto hba_fatal_err;
}
}
/* By this time rport_handle is valid */
}
return (FCT_SUCCESS);
/*
* XXX Throw HBA fatal error event
*/
return (FCT_FAILURE);
}
{
}
}
FCT_SUCCESS) {
return (ret);
}
}
return (FCT_SUCCESS);
}
{
if (accrjt == 1) {
} else {
}
}
{
char info[FCT_INFO_LEN];
int do_deregister = 0;
int irp_deregister_timer = 0;
if (irp->irp_els_list) {
}
if (irp_deregister_timer) {
if (ddi_get_lbolt() >= irp_deregister_timer) {
do_deregister = 1;
} else {
}
}
suggested_action |= ret;
if (!irp_deregister_timer ||
(do_deregister &&
!irp->irp_sa_elses_count &&
!irp->irp_nsa_elses_count &&
!irp->irp_fcp_xchg_count &&
!irp->irp_nonfcp_xchg_count)) {
/* dequeue irp from discovery queue */
if (do_deregister) {
/* queue irp for deregister */
if (!irp_dereg_list) {
irp_cur_item = irp;
} else {
irp;
irp_cur_item = irp;
}
} else {
}
break;
} else {
/*
* wait for another scan until
* deregister timeout
*/
}
} else {
/*
* When we dropped the lock,
* something went in.
*/
}
}
}
/* do deregister */
if (irp_dereg_list) {
/* drop the lock */
irp_cur_item->irp_dereg_count = 0;
/*
* It looks like we can't deregister it in the
* normal way, so we have to use extrem way
*/
"fct_walk_discovery_queue: "
"iport-%p, can't deregister irp-%p after "
"trying 5 times", (void *)iport,
(void *)irp_cur_item);
break;
} else {
/* grab the iport_lock */
/* recover */
ddi_get_lbolt() +
irp_cur_item, NULL);
}
}
}
return (suggested_action);
}
{
uint8_t *p;
char info[FCT_INFO_LEN];
int, (cmd_type != FCT_CMD_RCVD_ELS));
/* Trigger cleanup if necessary */
/* Cleanup everything except elses */
} else {
/* XXX: handle this */
/* EMPTY */
}
}
if (ddi_get_lbolt() > end_time) {
"fct_process_plogi: unable to "
"clean up I/O. iport-%p, icmd-%p", (void *)iport,
(void *)icmd);
return (DISC_ACTION_DELAY_RESCAN);
}
if ((ddi_get_lbolt() & 0x7f) == 0) {
" PLOGI rp_id %x, waiting for cmds to"
}
return (DISC_ACTION_DELAY_RESCAN);
}
irp->irp_session);
}
p[0] = ELS_OP_ACC;
}
if (ct_cmd) {
}
if (ct_cmd)
if (ct_cmd)
if (ct_cmd)
}
} else {
/*
* The reason we set this flag is to prevent
* killing a PRLI while we have not yet processed
* a response to PLOGI. Because the initiator
* will send a PRLI as soon as it responds to PLOGI.
* Check fct_process_els() for more info.
*/
if (ret != FCT_SUCCESS) {
}
}
}
if (ret == FCT_SUCCESS) {
if (cmd_type == FCT_CMD_RCVD_ELS) {
if (irp->irp_deregister_timer)
irp->irp_deregister_timer = 0;
}
if (icmd_flags & ICMD_IMPLICIT) {
int, (cmd_type != FCT_CMD_RCVD_ELS),
int, FCT_SUCCESS);
p = els->els_resp_payload;
p[0] = ELS_OP_ACC;
}
} else {
int, (cmd_type != FCT_CMD_RCVD_ELS),
int, ret);
}
/* Do not touch cmd here as it may have been freed */
return (DISC_ACTION_RESCAN);
}
0, 0, 0, 0 };
{
char info[FCT_INFO_LEN];
/* We dont support solicited PRLIs yet */
/*
* Dont process the PRLI yet. Let the framework process the
* PLOGI completion 1st. This should be very quick because
* the reason we got the PRLI is because the initiator
* has responded to PLOGI already.
*/
/* XXX: Probably need a timeout here */
return (DISC_ACTION_DELAY_RESCAN);
}
/* The caller has made sure that login is done */
/* Make sure the process is fcp in this case */
fct_prli_temp, 16))) {
else
goto prli_end;
}
if (irp->irp_fcp_xchg_count) {
/* Trigger cleanup if necessary */
} else {
/* XXX: handle this */
/* EMPTY */
}
}
if (ddi_get_lbolt() > end_time) {
"fct_process_prli: unable to clean "
"up I/O. iport-%p, icmd-%p", (void *)iport,
(void *)icmd);
return (DISC_ACTION_DELAY_RESCAN);
}
if ((ddi_get_lbolt() & 0x7f) == 0) {
" PRLI from %x, waiting for cmds to"
}
return (DISC_ACTION_DELAY_RESCAN);
}
irp->irp_session);
}
/* All good, lets start a session */
if (ses) {
STMF_SUCCESS) {
} else {
/*
* The reason IRP_SCSI_SESSION_STARTED is different
* from IRP_PRLI_DONE is that we clear IRP_PRLI_DONE
* inside interrupt context. We dont want to deregister
* the session from an interrupt.
*/
}
}
/* fail PRLI */
} else {
/* accept PRLI */
/* XXX the two bytes below need to set as per capabilities */
FCT_SUCCESS) {
} else {
/* Mark that PRLI is done */
}
}
prli_end:;
if (ret != FCT_SUCCESS)
return (DISC_ACTION_RESCAN);
}
{
char info[FCT_INFO_LEN];
/* Trigger cleanup if necessary */
/* Cleanup everything except elses */
} else {
/* XXX: need more handling */
return (DISC_ACTION_DELAY_RESCAN);
}
}
if (ddi_get_lbolt() > end_time) {
"fct_process_logo: unable to clean "
"up I/O. iport-%p, icmd-%p", (void *)iport,
(void *)icmd);
return (DISC_ACTION_DELAY_RESCAN);
}
if ((ddi_get_lbolt() & 0x7f) == 0) {
" LOGO rp_id %x, waiting for cmds to"
}
return (DISC_ACTION_DELAY_RESCAN);
}
irp->irp_session);
}
/* don't send response if this is an implicit logout cmd */
} else {
if (ret != FCT_SUCCESS) {
}
}
if (ret != FCT_SUCCESS) {
}
} else {
}
irp->irp_dereg_count = 0;
/* Do not touch cmd here as it may have been freed */
return (DISC_ACTION_RESCAN);
}
{
char info[FCT_INFO_LEN];
/* We do not support solicited PRLOs yet */
if (irp->irp_fcp_xchg_count) {
/* Trigger cleanup if necessary */
/* Cleanup everything except elses */
} else {
/* XXX: need more handling */
return (DISC_ACTION_DELAY_RESCAN);
}
}
if (ddi_get_lbolt() > end_time) {
"fct_process_prlo: unable to "
"clean up I/O. iport-%p, icmd-%p", (void *)iport,
(void *)icmd);
return (DISC_ACTION_DELAY_RESCAN);
}
if ((ddi_get_lbolt() & 0x7f) == 0) {
" PRLO from %x, waiting for cmds to"
}
return (DISC_ACTION_DELAY_RESCAN);
}
irp->irp_session);
}
if (ret != FCT_SUCCESS)
return (DISC_ACTION_RESCAN);
}
{
uint8_t *p;
uint32_t *q;
/* Validate the adisc request */
p = els->els_req_payload;
q = (uint32_t *)p;
} else {
p = els->els_resp_payload;
q = (uint32_t *)p;
p[0] = ELS_OP_ACC;
}
if (ret != FCT_SUCCESS) {
}
return (DISC_ACTION_RESCAN);
}
{
if (ret != FCT_SUCCESS) {
}
return (DISC_ACTION_RESCAN);
}
{
if (ret != FCT_SUCCESS) {
} else {
if (fct_rscn_options & RSCN_OPTION_VERIFY) {
}
}
} else {
ASSERT(0);
}
return (DISC_ACTION_RESCAN);
}
{
int dq;
/*
* Do some cleanup based on the following.
* - We can only have one session affecting els pending.
* - If any session affecting els is pending no other els is allowed.
* - If PLOGI is not done, nothing except PLOGI or LOGO is allowed.
* NOTE: If port is down the cleanup is done outside of this
* function.
* NOTE: There is a side effect, if a sa ELS (non PLOGI) is received
* while a PLOGI is pending, it will kill itself and the PLOGI.
* which is probably ok.
*/
int special_prli_cond = 0;
dq = 0;
/*
* The initiator sent a PRLI right after responding
* to PLOGI and we have not yet finished processing
* the PLOGI completion. We should not kill the PRLI
* as the initiator may not retry it.
*/
special_prli_cond = 1;
}
dq = 1;
dq = 1;
/* This els might have set the CLEANUP flag */
els->els_req_payload[0]);
} else if (irp->irp_sa_elses_count &&
els->els_req_payload[0]);
dq = 1;
(special_prli_cond == 0)) {
els->els_req_payload[0]);
dq = 1;
}
if (dq) {
else
cmd_to_abort = *ppcmd;
*ppcmd = c;
} else {
}
}
while (cmd_to_abort) {
cmd_to_abort = c;
}
/*
* pick from the top of the queue
*/
/*
* The cleanup took care of everything.
*/
return (DISC_ACTION_RESCAN);
}
}
if (op == ELS_OP_PLOGI) {
} else if (op == ELS_OP_PRLI) {
} else if (op == ELS_OP_LOGO) {
fct_status_t s;
"transport failed, ret = %llx", s);
}
} else if (op == ELS_OP_ADISC) {
} else if (op == ELS_OP_RSCN) {
(void) fct_process_rscn(icmd);
} else {
(void) fct_process_unknown_els(icmd);
}
/*
* This if condition will be false if a sa ELS trigged a cleanup
* and set the ret = DISC_ACTION_DELAY_RESCAN. In that case we should
* keep it that way.
*/
if (ret == DISC_ACTION_NO_WORK) {
/*
* Since we dropped the lock, we will force a rescan. The
* only exception is if someone returned
* DISC_ACTION_DELAY_RESCAN, in which case that should be the
* return value.
*/
}
return (ret);
}
void
{
}
if (irp->irp_deregister_timer) {
irp->irp_deregister_timer = 0;
irp->irp_dereg_count = 0;
}
}
}
}
static disc_action_t
{
int num_to_release, ndx;
if (total <= max_active)
return (DISC_ACTION_NO_WORK);
/*
* Everytime, we release half of the difference
*/
break;
}
}
return (DISC_ACTION_RESCAN);
}
/*
* The efficiency of handling solicited commands is very low here. But
* fortunately, we seldom send solicited commands. So it will not hurt
* the system performance much.
*/
static disc_action_t
{
/*
* This solicited cmd is new.
* Dispatch ELSes to discovery queue to make use of
* existent framework.
*/
} else {
}
/*
* To make fct_check_solcmd simple and flexible,
* We need only call callback to finish post-handling.
*/
/*
* mutex ???
*/
}
/*
* Release resources for this solicited cmd
*/
} else {
}
}
} else {
/*
* This solicited cmd is still ongoing.
* We need check if it's time to abort this cmd
*/
USEC_SOL_TIMEOUT)) < ddi_get_lbolt()) &&
icmd, FCT_ABORTED);
}
}
}
return (DISC_ACTION_DELAY_RESCAN);
}
void
{
/*
* Let's make sure local port is sane
*/
"solcmd-%p transport failed, becasue port state was %x",
return;
}
/*
* Let's make sure we have plogi-ed to name server
*/
"Must login to name server first - cmd-%p", cmd);
return;
}
/*
* Let's get a slot for this solcmd
*/
"ran out of xchg resources - cmd-%p", cmd);
return;
}
NS_GID_PN) {
if (query_irp) {
}
}
if (ret != FCT_SUCCESS) {
}
}
void
{
if (!FCT_IS_ELS_ACC(icmd)) {
"solicited LOGO is not accepted - icmd/%p", icmd);
}
}
void
{
int snlen = 0;
if (!FCT_IS_CT_ACC(icmd)) {
"GSNN is not accepted by NS - icmd/%p", icmd);
return;
}
if (!query_irp) {
"can't get rp icmd-%p", icmd);
goto exit_gsnn_cb;
} else {
}
/*
* Release previous resource, then allocate needed resource
*/
if (sn) {
}
}
/*
* Update symbolic node name
*/
(query_irp->irp_session)) {
}
} else {
}
}
void
{
if (!FCT_IS_ELS_ACC(icmd)) {
"fct_link_init_cb: ELS-%x is rejected",
} else {
}
} else {
if (!FCT_IS_CT_ACC(icmd)) {
"fct_link_init_cb: CT-%02x%02x is rejected",
} else {
}
}
}
void
{
if (!FCT_IS_CT_ACC(icmd)) {
"GCS_ID is not accepted by NS - icmd/%p", icmd);
return;
}
if (query_irp) {
}
}
void
{
if (!FCT_IS_CT_ACC(icmd)) {
"GFT_ID is not accepted by NS - icmd/%p", icmd);
return;
}
if (query_irp) {
}
}
void
{
int do_logo = 0;
query_irp->irp_rscn_counter))) {
"new RSCN arrived - query_irp/%p, private-%x", query_irp,
goto exit_gid_cb;
}
"not proper irp_flags - query_irp/%p", query_irp);
goto exit_gid_cb;
}
if (!FCT_IS_CT_ACC(icmd)) {
/*
* Check if it has disappeared
*/
"GPN_ID is not accepted by NS - icmd/%p", icmd);
do_logo = 1;
} else {
/*
* Check if its portid has changed
*/
"portid has changed - query_irp/%p", query_irp);
do_logo = 1;
}
}
if (do_logo) {
if (cmd) {
}
}
}
void
{
if (!FCT_IS_CT_ACC(icmd)) {
"GSPN_ID is not accepted by NS - icmd/%p", icmd);
return;
}
if (query_irp) {
if (spnlen > 0) {
}
}
}
}
void
{
if (!FCT_IS_ELS_ACC(icmd)) {
"solicited RLS is not accepted - icmd/%p", icmd);
if (rls_cb_data) {
}
return;
}
if (!rls_cb_data) {
return;
}
/* Get the response and store it somewhere */
}
/*
* For lookup functions, we move locking up one level
*/
{
int idx = 0;
continue;
} else {
return (irp);
}
}
}
return (NULL);
}
{
int idx = 0;
continue;
} else {
return (irp);
}
}
}
return (NULL);
}
#ifdef lint
#else
#define FCT_VERIFY_RSCN() \
do { \
fct_gid_cb); \
if (ct_cmd) { \
} \
} while (0)
#endif
/* ARGSUSED */
static void
{
int idx = 0;
uint8_t page_format = 0;
uint32_t page_portid = 0;
#ifndef lint
#endif
#ifndef lint
#endif
int, page_portid);
if (!page_format) {
continue; /* try next page */
}
continue; /* try next page */
}
} else {
continue; /* try next irp */
continue; /* try next irp */
continue; /* try next irp */
}
#ifndef lint
}
#endif
}
}
}
}
}