emlxs_fct.c revision 8f23e9fa8abcb5857661066b954e63400d589b65
/*
* 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
* 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
*/
/*
* Copyright (c) 2004-2012 Emulex. All rights reserved.
* Use is subject to license terms.
*/
#include <emlxs.h>
#ifdef SFCT_SUPPORT
/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
struct fct_flogi_xchg *fx);
void *arg2);
#ifdef FCT_IO_TRACE
int emlxs_iotrace_cnt = 0;
/*
*
* FCT_CMD (cmd_sbp->fct_state)
*
* STATE LOCK STATUS OWNER
* -----------------------------------------------------------------------------
* EMLXS_FCT_ABORT_DONE Lock Destroyed COMSTAR
* EMLXS_FCT_IO_DONE Lock Destroyed COMSTAR
*
* EMLXS_FCT_CMD_POSTED Lock Released COMSTAR
* EMLXS_FCT_OWNED Lock Released COMSTAR
*
* EMLXS_FCT_CMD_WAITQ Lock Released DRIVER
* EMLXS_FCT_RSP_PENDING Lock Released DRIVER
* EMLXS_FCT_REQ_PENDING Lock Released DRIVER
* EMLXS_FCT_REG_PENDING Lock Released DRIVER
* EMLXS_FCT_DATA_PENDING Lock Released DRIVER
* EMLXS_FCT_STATUS_PENDING Lock Released DRIVER
* EMLXS_FCT_CLOSE_PENDING Lock Released DRIVER
* EMLXS_FCT_ABORT_PENDING Lock Released DRIVER
*
* EMLXS_FCT_FCP_CMD_RECEIVED Transistional, lock held DRIVER
* EMLXS_FCT_ELS_CMD_RECEIVED Transistional, lock held DRIVER
* EMLXS_FCT_SEND_CMD_RSP Transistional, lock held DRIVER
* EMLXS_FCT_SEND_ELS_RSP Transistional, lock held DRIVER
* EMLXS_FCT_SEND_ELS_REQ Transistional, lock held DRIVER
* EMLXS_FCT_SEND_CT_REQ Transistional, lock held DRIVER
* EMLXS_FCT_REG_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_SEND_FCP_DATA Transistional, lock held DRIVER
* EMLXS_FCT_SEND_FCP_STATUS Transistional, lock held DRIVER
* EMLXS_FCT_PKT_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_PKT_FCPRSP_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_PKT_ELSRSP_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_PKT_ELSCMD_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_PKT_CTCMD_COMPLETE Transistional, lock held DRIVER
* EMLXS_FCT_REQ_COMPLETE Transistional, lock held DRIVER
*
*
* COMSTAR OWNED DRIVER OWNED
* ------------- ---------------------------------------------------
* ------- > @ Accept---- >Release @ Acquire--- >+
* |
*
* @ :Indicates COMSTAR use of emlxs_fct_abort()
* Abort requests set the EMLXS_FCT_ABORT_INP flag.
*
* Accept :Indicates use of emlxs_fct_cmd_accept()
* Acquire :Indicates use of emlxs_fct_cmd_acquire()
* Post :Indicates use of emlxs_fct_cmd_post()
* Done :Indicates use of emlxs_fct_cmd_done()
*/
void
{
int i;
if (!iop) {
return;
}
switch (data) {
/* New entry */
case EMLXS_FCT_SEND_ELS_REQ:
case EMLXS_FCT_SEND_CT_REQ:
for (i = 0; i < iotrace_cnt; i++) {
break;
iop++;
}
if (i < iotrace_cnt) {
/* New entry already exists */
"IOTRACE: New entry already exists: fct_cmd: %p",
fct_cmd);
return;
}
for (i = 0; i < iotrace_cnt; i++) {
break;
iop++;
}
if (i >= iotrace_cnt) {
/* No new slots available */
"IOTRACE: No new slots: fct_cmd: %p data: %d",
return;
}
port->iotrace_index++;
port->iotrace_index = 0;
return;
}
for (i = 0; i < iotrace_cnt; i++) {
break;
iop++;
}
if (i >= iotrace_cnt) {
/* Cannot find existing slot for fct_cmd */
if ((data != EMLXS_FCT_REG_PENDING) &&
(data != EMLXS_FCT_REG_COMPLETE)) {
"IOTRACE: Missing slot: fct_cmd: %p data: %d",
}
return;
}
/* trc overrun for fct_cmd */
"IOTRACE: trc overrun slot: fct_cmd: %p data: %d",
return;
}
/* xri mismatch for fct_cmd */
"IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d",
return;
}
/* IOCB ULPCOMMAND is saved after EMLXS_FCT_IOCB_ISSUED */
} else {
} else {
}
return;
} /* emlxs_fct_io_trace() */
#endif /* FCT_IO_TRACE */
#ifdef MODSYM_SUPPORT
extern int
{
int err;
if (emlxs_modsym.fct_modopen) {
return (0);
}
/* Comstar (fct) */
err = 0;
if (!emlxs_modsym.mod_fct) {
DRIVER_NAME, err);
goto failed;
}
/* Comstar (stmf) */
err = 0;
if (!emlxs_modsym.mod_stmf) {
DRIVER_NAME, err);
goto failed;
}
err = 0;
/* Check if the fct fct_alloc is present */
"fct_alloc", &err);
"?%s: drv/fct: fct_alloc not present", DRIVER_NAME);
goto failed;
}
err = 0;
/* Check if the fct fct_free is present */
"fct_free", &err);
"?%s: drv/fct: fct_free not present", DRIVER_NAME);
goto failed;
}
err = 0;
/* Check if the fct fct_scsi_task_alloc is present */
"fct_scsi_task_alloc", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_register_local_port is present */
"fct_register_local_port", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_deregister_local_port is present */
"fct_deregister_local_port", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_handle_event is present */
&err);
goto failed;
}
err = 0;
/* Check if the fct fct_post_rcvd_cmd is present */
&err);
goto failed;
}
err = 0;
/* Check if the fct fct_alloc is present */
"fct_ctl", &err);
"?%s: drv/fct: fct_ctl not present", DRIVER_NAME);
goto failed;
}
err = 0;
/* Check if the fct fct_queue_cmd_for_termination is present */
"fct_queue_cmd_for_termination", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_send_response_done is present */
"fct_send_response_done", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_send_cmd_done is present */
&err);
goto failed;
}
err = 0;
/* Check if the fct fct_scsi_xfer_data_done is present */
"fct_scsi_data_xfer_done", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_port_shutdown is present */
"fct_port_shutdown", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_port_initialize is present */
"fct_port_initialize", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_cmd_fca_aborted is present */
"fct_cmd_fca_aborted", &err);
goto failed;
}
err = 0;
/* Check if the fct fct_handle_rcvd_flogi is present */
"fct_handle_rcvd_flogi", &err);
goto failed;
}
/* Comstar (stmf) */
err = 0;
/* Check if the stmf stmf_alloc is present */
&err);
"?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME);
goto failed;
}
err = 0;
/* Check if the stmf stmf_free is present */
"stmf_free", &err);
"?%s: drv/stmf: stmf_free not present", DRIVER_NAME);
goto failed;
}
err = 0;
/* Check if the stmf stmf_deregister_port_provider is present */
"stmf_deregister_port_provider", &err);
goto failed;
}
err = 0;
/* Check if the stmf stmf_register_port_provider is present */
"stmf_register_port_provider", &err);
goto failed;
}
return (0);
return (1);
} /* emlxs_fct_modopen() */
extern void
{
if (emlxs_modsym.fct_modopen == 0) {
return;
}
if (emlxs_modsym.fct_modopen) {
return;
}
if (emlxs_modsym.mod_fct) {
emlxs_modsym.mod_fct = 0;
}
if (emlxs_modsym.mod_stmf) {
emlxs_modsym.mod_stmf = 0;
}
} /* emlxs_fct_modclose() */
#endif /* MODSYM_SUPPORT */
/*
* This routine is called to handle an unsol FLOGI exchange
* fx save
* 0 1 Process or save port->fx
* 0 0 Process or reject port->fx
* 1 1 Process port->fx, Process or save fx
* 1 0 Process or reject port->fx, Process or reject fx
*/
static void
{
/* Check if there is an old saved FLOGI */
/* Get it now */
if (fx) {
/* Save new FLOGI */
/* Reject old stale FLOGI */
goto reject_it;
} else {
}
} else if (!fx) {
/* Nothing to do, just return */
return;
}
/* We have a valid FLOGI here */
/* There is no saved FLOGI at this point either */
/* Check if COMSTAR is ready to accept it */
#ifdef FCT_API_TRACE
"fct_handle_rcvd_flogi %p: status=%x",
#endif /* FCT_API_TRACE */
if (status == FCT_SUCCESS) {
ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0);
} else { /* ELS_OP_LSRJT */
}
} else {
"FLOGI: sid=%x xid=%x. "
"fct_handle_rcvd_flogi failed. Rejecting.",
}
return;
}
if (save) {
/* Save FLOGI for later */
return;
}
"FLOGI: sid=%x xid=%x. Stale. Rejecting.",
/* If we have an FLOGI saved, try sending it now */
goto begin;
}
} else {
"FLOGI: sid=%x xid=%x. Link down. "
"Dropping.",
}
return;
} /* emlxs_fct_handle_unsol_flogi() */
/* ARGSUSED */
static void
{
return;
} /* emlxs_fct_unsol_flush_thread() */
/* This is called at port online and offline */
static void
{
return;
}
/* First handle any pending FLOGI */
return;
}
/* Wait queue */
/*
* Next process any outstanding ELS commands. It doesn't
* matter if the Link is up or not, always post them to FCT.
*/
while (cmd_sbp) {
/* Reacquire ownership of the fct_cmd */
if (rval) {
"fct_unsol_flush: %s: sid=%x xid=%x "
"Unable to reacquire fct_cmd.",
continue;
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
"Posting %s: sid=%x xid=%x %p",
fct_cmd);
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
} /* while () */
return;
} /* emlxs_fct_unsol_flush() */
int
{
return (1);
}
return (0);
} /* emlxs_is_digit */
/*
* Convert an ASCII decimal numeric string to integer.
* Negation character '-' is not handled.
*/
static uint32_t
{
int i = 0;
while (string[i]) {
if (!emlxs_is_digit(string[i])) {
return (num);
}
}
return (num);
} /* emlxs_str_atoi() */
extern uint32_t
{
/* Check if COMSTAR is present */
"Comstar not present.");
return (1);
}
return (0);
} /* emlxs_fct_init() */
extern void
{
return;
}
/* Bind the physical port */
/* Bind virtual ports */
continue;
}
}
}
return;
} /* emlxs_fct_attach() */
extern void
{
uint32_t i;
for (i = 0; i < MAX_VPORTS; i++) {
continue;
}
}
#ifdef FCT_IO_TRACE
{
}
}
#endif /* FCT_IO_TRACE */
return;
} /* emlxs_fct_detach() */
extern void
{
char node_name[32];
return;
}
/* Destroy & flush all port nodes, if they exist */
if (port->node_count) {
}
hba->num_of_ports--;
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
if (port->port_provider) {
#ifdef FCT_API_TRACE
"stmf_deregister_port_provider:1 %p",
#endif /* FCT_API_TRACE */
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
if (port->fct_memseg) {
}
return;
} /* emlxs_fct_unbind_port() */
extern void
{
char node_name[32];
return;
}
return;
}
/* Perform generic port initialization */
} else {
}
"fct_bind_port: Unable to allocate fct memory.");
goto failed;
}
flag |= 0x00000001;
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
"fct_bind_port: Unable to allocate port provider.");
goto failed;
}
flag |= 0x00000002;
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
/* register port provider with framework */
STMF_SUCCESS) {
"fct_bind_port: Unable to register port provider.");
goto failed;
}
flag |= 0x00000004;
0);
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
"fct_bind_port: Unable to allocate fct port.");
goto failed;
}
flag |= 0x00000008;
0);
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
"fct_bind_port: Unable to allocate dbuf store.");
goto failed;
}
flag |= 0x00000010;
NULL, 0) == DDI_FAILURE) {
"Unable to create SFCT device node.");
goto failed;
}
flag |= 0x00000020;
/* Intialize */
"%02x%02x%02x%02x%02x%02x%02x%02x",
"%02x%02x%02x%02x%02x%02x%02x%02x",
} else {
}
/* Scatter gather list support */
/* fds->fds_setup_dbuf = ; */
/* fds->fds_teardown_dbuf = ; */
/* fds->fds_max_sgl_xfer_len = ; */
/* fds->fds_copy_threshold = ; */
#ifdef FCT_API_TRACE
"fct_register_local_port %p", fct_port);
#endif /* FCT_API_TRACE */
/* register this local port with the fct module */
"fct_bind_port: Unable to register fct port.");
goto failed;
}
/* Set the bound flag */
hba->num_of_ports++;
return;
if (flag & 0x20) {
}
if (flag & 0x10) {
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
if (flag & 0x8) {
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
if (flag & 0x4) {
#ifdef FCT_API_TRACE
"stmf_deregister_port_provider:2 %p",
#endif /* FCT_API_TRACE */
}
if (flag & 0x2) {
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
}
if (flag & 0x1) {
}
"Target mode disabled.");
return;
} /* emlxs_fct_bind_port() */
/* COMSTAR ENTER POINT */
/*ARGSUSED*/
static fct_status_t
{
switch (cmd) {
case FC_TGT_PORT_RLS:
if ((*size) < sizeof (fct_port_link_status_t)) {
"FC_TGT_PORT_RLS: Buffer too small. %d < %d",
*size, sizeof (fct_port_link_status_t));
rval = FCT_FAILURE;
break;
}
"FC_TGT_PORT_RLS: Unable to allocate mailbox.");
break;
}
!= MBX_SUCCESS) {
"FC_TGT_PORT_RLS: Unable to send request.");
} else {
}
break;
default:
"fct_port_info: Invalid request. cmd=%x",
cmd);
rval = FCT_FAILURE;
break;
}
return (rval);
} /* emlxs_fct_port_info() */
/* COMSTAR ENTER POINT */
static void
{
"%s (%s)", emlxs_version,
}
}
}
}
}
}
"Port attr: model_description = %s",
"Port attr: hardware_version = %s",
"Port attr: option_rom_version = %s",
"Port attr: firmware_version = %s",
"Port attr: vendor_specific_id = 0x%x",
"Port attr: supported_cos = 0x%x",
"Port attr: supported_speed = 0x%x",
"Port attr: max_frame_size = 0x%x",
return;
} /* emlxs_fct_populate_hba_details() */
/* COMSTAR ENTER POINT */
/* ARGSUSED */
static void
{
switch (cmd) {
case FCT_CMD_PORT_ONLINE:
/* If the HBA is offline, we cannot bring the tgtport online */
break;
}
"STATE: ONLINE chk");
} else {
"STATE: OFFLINE --> ONLINE");
/* Try to bring the link up */
}
"STATE: ONLINE");
}
break;
case FCT_CMD_PORT_OFFLINE:
"STATE: OFFLINE chk");
} else {
"STATE: ONLINE --> OFFLINE");
/* Take link down and flush */
/* Declare this port offline now */
/* Take link down and hold it down */
}
"STATE: OFFLINE");
}
break;
"STATE: OFFLINE ack");
break;
"STATE: ONLINE ack");
break;
case FCT_CMD_FORCE_LIP:
"fct_ctl: FCT_CMD_FORCE_LIP.");
break;
}
"fct_ctl: FCT_CMD_FORCE_LIP -> "
"FCT_CMD_RESET");
/* Reset the adapter */
} else {
"fct_ctl: FCT_CMD_FORCE_LIP");
/* Reset the link */
}
break;
}
return;
} /* emlxs_fct_ctl() */
extern int
{
int i;
if (!fct_port) {
return (0);
}
DRIVER_NAME" shutdown");
i = 0;
i++;
if (i > 300) { /* 30 seconds */
"fct_port_shutdown failed to ACK");
break;
}
}
return (1);
}
extern int
{
int i;
if (!fct_port) {
return (0);
}
"fct_port_initialize");
DRIVER_NAME" initialize");
i = 0;
i++;
if (i > 300) { /* 30 seconds */
"fct_port_initialize failed to ACK");
break;
}
}
return (1);
}
/* COMSTAR ENTER POINT */
static fct_status_t
{
#ifdef FCT_API_TRACE
"fct_send_cmd %p:%p x%x", fct_cmd,
#endif /* FCT_API_TRACE */
case FCT_CMD_SOL_ELS:
return (emlxs_fct_send_els_cmd(fct_cmd));
case FCT_CMD_SOL_CT:
return (emlxs_fct_send_ct_cmd(fct_cmd));
default:
"fct_send_cmd: Invalid cmd type found. type=%x",
return (FCT_FAILURE);
}
} /* emlxs_fct_send_cmd() */
/* COMSTAR ENTER POINT */
static fct_status_t
{
if (rval) {
"fct_send_cmd_rsp: "
"Unable to accept fct_cmd. type=%x",
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_cmd_rsp %p:%p x%x, %x, %x",
#endif /* FCT_API_TRACE */
case FCT_CMD_FCP_XCHG:
if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
goto failure;
}
/* Firmware already sent out resp */
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_response_done:4 %p: x%x",
#endif /* FCT_API_TRACE */
return (FCT_SUCCESS);
}
if (rval == FCT_NOT_FOUND) {
goto failure;
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (rval);
case FCT_CMD_RCVD_ELS:
if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
goto failure;
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (rval);
default:
if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
fct_cmd->cmd_handle = 0;
}
"fct_send_cmd_rsp: Invalid cmd type found. type=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_FAILURE);
}
"fct_send_cmd_rsp: "
"Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_FAILURE);
} /* emlxs_fct_send_cmd_rsp() */
/* COMSTAR ENTER POINT */
static fct_status_t
{
#ifdef FCT_API_TRACE
"fct_flogi_xchg: Sending FLOGI: %p", fct_port);
#else
"fct_flogi_xchg: Sending FLOGI.");
#endif /* FCT_API_TRACE */
"fct_flogi_xchg: FLOGI failed. Link down.");
rval = FCT_FAILURE;
goto done;
}
/* Use this entry point as the link up acknowledgment */
"fct_link_up acked.");
/* First handle any pending FLOGI's */
"fct_flogi_xchg: FLOGI failed. "
"Unable allocate packet.");
rval = FCT_FAILURE;
goto done;
}
/* Make this a polled IO */
/* Build the fc header */
/* Build the command */
/* Service paramters will be added automatically later by the driver */
"fct_flogi_xchg: FLOGI failed. "
"Unable to send packet.");
rval = FCT_FAILURE;
goto done;
}
rval = FCT_TIMEOUT;
} else {
rval = FCT_FAILURE;
}
"fct_flogi_xchg: FLOGI failed. state=%x reason=%x "
goto done;
}
} else { /* FC_PKT_SUCCESS */
}
done:
if (pkt) {
}
"fct_flogi_xchg: FCT_STATE_FLOGI_CMPL. rval=%s",
/*
* Flush all unsolicited commands
* Must use separate thread since
* this thread must complete first
*/
(void *)port, 0);
}
return (rval);
} /* emlxs_fct_flogi_xchg() */
/* COMSTAR ENTER POINT */
/* This is called right after we report that link has come online */
static fct_status_t
{
"fct_get_link_info %p: FCT: flg x%x HBA: ste x%x flg x%x topo x%x",
return (FCT_SUCCESS);
}
return (FCT_SUCCESS);
}
} else {
}
case LA_1GHZ_LINK:
break;
case LA_2GHZ_LINK:
break;
case LA_4GHZ_LINK:
break;
case LA_8GHZ_LINK:
break;
case LA_10GHZ_LINK:
break;
case LA_16GHZ_LINK:
break;
default:
break;
}
link->port_no_fct_flogi = 0;
link->port_fca_flogi_done = 0;
link->port_fct_flogi_done = 0;
return (FCT_SUCCESS);
} /* emlxs_fct_get_link_info() */
/* COMSTAR ENTER POINT */
static fct_status_t
{
uint32_t i;
#ifdef FCT_API_TRACE
"fct_register_remote_port %p", fct_port);
#endif /* FCT_API_TRACE */
/* mutex_enter(&cmd_sbp->fct_mtx); */
} else {
if (rval) {
"fct_register_remote_port: "
"Unable to accept fct_cmd. lid=%x rid=%x",
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
}
/* Check for unsolicited PLOGI */
sizeof (uint32_t));
} else { /* Solicited PLOGI */
sizeof (SERV_PARM));
/*
* Create temporary WWN's from fct_cmd address
* This simply allows us to get an RPI from the
* adapter until we get real service params.
* The PLOGI ACC reply will trigger a REG_LOGIN
* update later
*/
}
/*
* We already received the remote port's
* parameters in the FLOGI exchange
*/
sizeof (SERV_PARM));
/*
* Since this is a PLOGI, not a FLOGI, we need
* to fix up word2 of the CSP accordingly.
*/
}
}
"fct_register_remote_port: Register lid=%x rid=%x. (%x,%x,%p)",
/* mutex_exit(&cmd_sbp->fct_mtx); */
/* Create a new node */
"fct_register_remote_port: "
"Reg login failed. lid=%x rid=%x",
} else {
/* Wait for completion */
pkt_ret = 0;
while ((pkt_ret != -1) &&
}
}
/* Reacquire ownership of the fct_cmd */
if (rval2) {
"fct_register_remote_port: "
"Unable to reacquire fct_cmd. lid=%x rid=%x",
return (rval2);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* Prepare response */
if (ndlp) {
if (hdl == FABRIC_RPI) {
/* The SCR handle is hardcoded */
} else {
for (i = 1; i < EMLXS_FCT_NUM_ELS_ONLY; i++) {
continue;
/*
* Bit is not set, so use this
* for the handle
*/
break;
}
if (i >= EMLXS_FCT_NUM_ELS_ONLY) {
}
}
} else {
}
}
"fct_register_remote_port: lid=%x rid=%x hdl=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_SUCCESS);
} else {
"fct_register_remote_port: failed. lid=%x rid=%x hdl=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_FAILURE);
}
} /* emlxs_fct_register_remote_port() */
/* COMSTAR ENTER POINT */
static fct_status_t
{
uint32_t i;
#ifdef FCT_API_TRACE
"fct_deregister_remote_port: did=%x hdl=%x",
#else
"fct_deregister_remote_port: did=%x hdl=%x",
#endif /* FCT_API_TRACE */
if ((i < EMLXS_FCT_NUM_ELS_ONLY) &&
}
}
if (ndlp) {
}
return (FCT_SUCCESS);
} /* emlxs_fct_deregister_remote_port() */
/* ARGSUSED */
extern int
{
if (!ndlp) {
"FCP rcvd: Unknown RPI. rpi=%d rxid=%x. Dropping...",
goto dropped;
}
"FCP rcvd: Target unbound. rpi=%d rxid=%x. Dropping...",
goto dropped;
}
"FCP rcvd: Target offline. rpi=%d rxid=%x. Dropping...",
goto dropped;
}
/* Get lun id */
}
}
fct_cmd =
"FCP rcvd: sid=%x xid=%x. "
"Unable to allocate scsi task. Returning QFULL.",
goto dropped;
}
/* Initialize fct_cmd */
/* mutex_enter(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_scsi_task_alloc %p:%p FCP rcvd: "
"cmd=%x sid=%x rxid=%x oxid=%x lun=%02x%02x dl=%d",
#endif /* FCT_API_TRACE */
/* Initialize cmd_sbp */
/* xrip was setup / passed in from the SLI layer */
#ifdef FCT_API_TRACE
"FCP rcvd: oxid=%x rxid=%x iotag=%d %p ",
#endif /* FCT_API_TRACE */
} else {
}
}
/* Set task_flags */
case SIMPLE_Q:
break;
case HEAD_OF_Q:
break;
case ORDERED_Q:
break;
case ACA_Q:
break;
case UNTAGGED:
break;
}
case 0:
break;
case 1:
break;
case 2:
break;
}
fct_task->task_priority = 0;
/* task_mgmt_function */
if (tm) {
} else {
}
}
/* Parallel buffers support - future */
fct_task->task_cur_nbufs = 0;
fct_task->task_cmd_seq_no = 0;
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_post_rcvd_cmd:3 %p:%p portid x%x, %d outio %d",
#endif /* FCT_API_TRACE */
return (0);
return (1);
} /* emlxs_fct_handle_unsol_req() */
/* COMSTAR ENTER POINT */
/* ARGSUSED */
static fct_status_t
{
emlxs_port_t *port =
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
int channel;
int channelno;
fct_status_t rval = 0;
if (rval) {
"fct_send_fcp_data: "
"Unable to accept fct_cmd. did=%x",
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
#ifdef FCT_API_TRACE
"fct_send_fcp_data %p:%p flgs=%x ioflags=%x dl=%d,%d,%d,%d",
#endif /* FCT_API_TRACE */
/* Setup for I/O prep routine */
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_BUSY);
}
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
}
return (FCT_BUSY);
}
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_SUCCESS);
} /* emlxs_fct_send_fcp_data() */
/* cmd_sbp->fct_mtx must be held to enter */
/* cmd_sbp->fct_mtx must be released before exiting */
static fct_status_t
{
emlxs_port_t *port =
/* Initialize cmd_sbp */
size = 24;
if (fct_task->task_sense_length) {
}
#ifdef FCT_API_TRACE
"fct_send_fcp_status %p:%p stat=%d resid=%d size=%d rx=%x ox=%x",
#endif /* FCT_API_TRACE */
"fct_send_fcp_status: Unable to allocate packet.");
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_BUSY);
}
pkt->pkt_timeout =
/* Build the fc header */
/* Build the status payload */
if (fct_task->task_resid) {
}
}
if (fct_task->task_scsi_status) {
} else {
}
/* Make sure residual reported on non-SCSI_GOOD READ status */
}
}
if (fct_task->task_sense_length) {
}
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
/* mutex_exit(&cmd_sbp->fct_mtx); */
"fct_send_fcp_status: Unable to send packet.");
}
/* Reacquire ownership of the fct_cmd */
if (rval) {
"fct_send_fcp_status: "
"Unable to acquire fct_cmd.");
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_BUSY);
}
return (FCT_SUCCESS);
} /* emlxs_fct_send_fcp_status() */
static fct_status_t
{
size = 24;
"fct_send_qfull_reply: Unable to allocate packet.");
return (FCT_FAILURE);
}
pkt->pkt_timeout =
/* Build the fc header */
"fct_send_qfull_reply: Sending QFULL: x%x lun x%x: %d %d",
/* Build the status payload */
}
"fct_send_qfull_reply: Unable to send packet.");
return (FCT_FAILURE);
}
return (FCT_SUCCESS);
} /* emlxs_fct_send_qfull_reply() */
/* ARGSUSED */
extern int
{
if (!sbp) {
/* completion with missing xmit command */
/* emlxs_stray_fcp_completion_msg */
"FCP event cmd=%x status=%x error=%x iotag=%d",
return (1);
}
#ifdef FCT_API_TRACE
"fct_handle_fcp_event: %p:%p cmd=%x status=%x, %x",
#endif /* FCT_API_TRACE */
/* For driver generated QFULL response */
}
return (0);
}
if (rval) {
"fct_handle_fcp_event: "
"Unable to reacquire fct_cmd. type=%x",
return (1);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
if (status) {
/*
* The error indicates this IO should be terminated
* immediately.
*/
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_queue_cmd_for_termination:1 %p: x%x",
#endif /* FCT_API_TRACE */
goto done;
}
switch (iocb->ULPCOMMAND) {
/*
* FCP Data completion
*/
case CMD_FCP_TSEND_CX:
case CMD_FCP_TSEND64_CX:
case CMD_FCP_TRECEIVE_CX:
case CMD_FCP_TRECEIVE64_CX:
goto emlxs_dma_error;
}
}
fct_task =
fct_task->task_scsi_status = 0;
(void) emlxs_fct_send_fcp_status(fct_cmd);
/* mutex_exit(&cmd_sbp->fct_mtx); */
break;
/* Auto-resp has been sent out by firmware */
/* We can assume this is really a FC_TRSP_CX */
fct_task =
fct_task->task_scsi_status = 0;
goto auto_resp;
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
break;
/* FCP Status completion */
case CMD_FCP_TRSP_CX:
case CMD_FCP_TRSP64_CX:
/* Copy these before calling emlxs_fct_cmd_done */
/* mutex_exit(&cmd_sbp->fct_mtx); */
if (fct_flags & EMLXS_FCT_SEND_STATUS) {
#ifdef FCT_API_TRACE
"fct_scsi_data_xfer_done:2 %p %p outio %d",
#endif /* FCT_API_TRACE */
} else {
#ifdef FCT_API_TRACE
"fct_send_response_done:1 %p: x%x outio %d",
#endif /* FCT_API_TRACE */
}
break;
default:
/* mutex_exit(&cmd_sbp->fct_mtx); */
if (pkt) {
}
} /* switch(iocb->ULPCOMMAND) */
done:
if (pkt) {
}
if (status == IOSTAT_SUCCESS) {
} else {
}
return (0);
} /* emlxs_fct_handle_fcp_event() */
/* ARGSUSED */
extern int
{
if (!sbp) {
/* completion with missing xmit command */
/* emlxs_stray_fcp_completion_msg */
"ABORT event cmd=%x status=%x error=%x iotag=%d",
return (1);
}
#ifdef FCT_API_TRACE
"fct_handle_abort: %p:%p xri=%d cmd=%x status=%x",
#endif /* FCT_API_TRACE */
goto exit;
}
"Cmd not aborted, retrying: xri=%d iotag=%d sbp=%p",
/* Abort retry */
} else {
return (0);
}
}
}
exit:
if (pkt) {
}
return (0);
} /* emlxs_fct_handle_abort() */
extern int
{
"%s: sid=%x. Adapter offline. Dropping...",
goto done;
}
switch (cmd_code) {
case ELS_CMD_LOGO:
case ELS_CMD_PRLO:
"%s: sid=%x. Target unbound. Accepting...",
ELS_CMD_LOGO, 0, 0);
break;
default:
"%s: sid=%x. Target unbound. Rejecting...",
break;
}
goto done;
}
"%s: sid=%x. Target offline. Rejecting...",
goto done;
}
#ifdef FCT_API_TRACE
"%s: sid=%x cnt=%d. Target rcv. ",
#endif /* FCT_API_TRACE */
/* Process the request */
switch (cmd_code) {
case ELS_CMD_FLOGI:
if (!rval) {
/* Save the FLOGI exchange information */
}
goto done;
case ELS_CMD_PLOGI:
rval =
break;
default:
rval = 0;
break;
}
if (rval) {
goto done;
}
#ifdef FCT_API_TRACE
{
"fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x",
}
#endif /* FCT_API_TRACE */
"%s: sid=%x. Out of memory. Rejecting...",
goto done;
}
/* Initialize fct_cmd */
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* Initialize cmd_sbp */
sizeof (emlxs_iocb_t));
/* Check if Offline */
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd,
#endif /* FCT_API_TRACE */
goto done;
}
/* Online */
/* Check if Link up is acked */
goto defer;
}
if ((cmd_code != ELS_CMD_FLOGI) &&
goto defer;
}
/* Post it to COMSTAR */
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd,
#endif /* FCT_API_TRACE */
goto done;
/* Defer processing of fct_cmd till later (after link up ack). */
"%s: sid=%x. Defer Processing x%x.",
/* mutex_exit(&cmd_sbp->fct_mtx); */
/* Add cmd_sbp to queue tail */
if (port->fct_wait_tail) {
}
if (!port->fct_wait_head) {
}
done:
return (0);
} /* emlxs_fct_handle_unsol_els() */
/* ARGSUSED */
static uint32_t
{
char buffer[64];
buffer[0] = 0;
/* Perform processing of FLOGI payload */
sizeof (buffer))) {
return (1);
}
"FLOGI: sid=0x%x xid=%x %s",
return (0);
} /* emlxs_fct_process_unsol_flogi() */
/* ARGSUSED */
static uint32_t
{
char buffer[64];
buffer[0] = 0;
/* Perform processing of PLOGI payload */
sizeof (buffer))) {
return (1);
}
"PLOGI: sid=0x%x xid=%x %s",
return (0);
} /* emlxs_fct_process_unsol_plogi() */
/* ARGSUSED */
static emlxs_buf_t *
{
return (sbp);
} /* emlxs_fct_pkt_init() */
/* Mutex will be acquired */
static emlxs_buf_t *
{
/* Flags fct_cmd as inuse */
}
if (fct_state) {
}
return (cmd_sbp);
} /* emlxs_fct_cmd_init() */
/* Called after receiving fct_cmd from COMSTAR */
static fct_status_t
{
"fct_cmd_accept: "
"Invalid fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_accept:2 "
"Invalid fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_accept: "
"Aborted fct_cmd found! fct_cmd=%p state=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_NOT_FOUND);
}
"fct_cmd_accept: "
"Busy fct_cmd found! fct_cmd=%p state=%x",
return (FCT_BUSY);
}
if (fct_state) {
}
return (FCT_SUCCESS);
} /* emlxs_fct_cmd_accept() */
/* Called after receiving fct_cmd from driver */
static fct_status_t
{
"fct_cmd_acquire: "
"Bad fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire: "
"Invalid fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire: "
"Returned fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire:2 "
"Bad fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire:2 "
"Invalid fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire:2 "
"Returned fct_cmd found! fct_cmd=%p state=%x",
return (FCT_NOT_FOUND);
}
"fct_cmd_acquire: "
"Aborting cmd. fct_cmd=%p state=%x",
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_NOT_FOUND);
}
if (fct_state) {
}
return (FCT_SUCCESS);
} /* emlxs_fct_cmd_acquire() */
/* cmd_sbp->fct_mtx must be held to enter */
/* cmd_sbp->fct_mtx must be released before exiting */
/* Called before transitionally sending fct_cmd to driver */
/*ARGSUSED*/
static void
{
if (fct_state) {
}
return;
} /* emlxs_fct_cmd_release() */
/* cmd_sbp->fct_mtx must be held to enter */
/* cmd_sbp->fct_mtx must be released before exiting */
/* Called before posting fct_cmd back to COMSTAR */
/*ARGSUSED*/
static void
{
if (fct_state) {
}
if (pkt) {
}
return;
} /* emlxs_fct_cmd_post() */
/* cmd_sbp->fct_mtx must be held to enter */
/* Called before completing fct_cmd back to COMSTAR */
static void
{
/* Flags fct_cmd is no longer used */
"Pkt still registered! channel=%p iotag=%d sbp=%p",
} else {
}
}
}
if (fct_state) {
}
if (pkt) {
}
return;
} /* emlxs_fct_cmd_done() */
static void
{
#ifdef FMA_SUPPORT
#endif /* FMA_SUPPORT */
#ifdef FMA_SUPPORT
#endif /* FMA_SUPPORT */
if (rval) {
"fct_pkt_comp: "
"Unable to reacquire fct_cmd.");
return;
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
case FCT_CMD_FCP_XCHG:
/*
* The error indicates this IO should be terminated
* immediately.
*/
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_queue_cmd_for_termination:2 %p:%p x%x",
#endif /* FCT_API_TRACE */
break;
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_response_done:2 %p:%p x%x outio %d",
#else
"fct_pkt_comp: fct_send_response_done. dbuf=%p",
#endif /* FCT_API_TRACE */
break;
case FCT_CMD_RCVD_ELS:
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_response_done:3 %p:%p x%x",
#endif /* FCT_API_TRACE */
break;
case FCT_CMD_SOL_ELS:
if (fct_els->els_resp_payload) {
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_cmd_done:1 %p:%p x%x",
#endif /* FCT_API_TRACE */
#ifdef FMA_SUPPORT
!= DDI_FM_OK) {
"fct_pkt_comp: hdl=%p",
pkt->pkt_resp_dma);
break;
}
#endif /* FMA_SUPPORT */
break;
case FCT_CMD_SOL_CT:
if (fct_ct->ct_resp_payload) {
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
#ifdef FCT_API_TRACE
"fct_send_cmd_done:2 %p:%p x%x",
#endif /* FCT_API_TRACE */
#ifdef FMA_SUPPORT
!= DDI_FM_OK) {
"fct_pkt_comp: hdl=%p",
pkt->pkt_resp_dma);
break;
}
#endif /* FMA_SUPPORT */
break;
default:
"fct_pkt_comp: Invalid cmd type found. type=%x",
/* mutex_exit(&cmd_sbp->fct_mtx); */
break;
}
return;
} /* emlxs_fct_pkt_comp() */
static void
{
#ifdef FCT_API_TRACE
"fct_abort_pkt_comp: %p: xri=%d cmd=%x status=%x",
#endif /* FCT_API_TRACE */
return;
} /* emlxs_fct_abort_pkt_comp() */
/* COMSTAR ENTER POINT (INDIRECT) */
static fct_status_t
{
emlxs_port_t *port =
"fct_send_els_cmd: Unable to allocate packet.");
return (FCT_BUSY);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
pkt->pkt_timeout =
"fct_send_els_cmd: pkt_timeout=%d ratov=%d",
/* Build the fc header */
/* Copy the cmd payload */
/* mutex_exit(&cmd_sbp->fct_mtx); */
"fct_send_els_cmd: Unable to send packet.");
/* Reacquire ownership of the fct_cmd */
if (rval) {
"fct_send_els_cmd: "
"Unable to reacquire fct_cmd.");
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_BUSY);
}
return (FCT_SUCCESS);
} /* emlxs_fct_send_els_cmd() */
/* cmd_sbp->fct_mtx must be held to enter */
/* cmd_sbp->fct_mtx must be released before exiting */
static fct_status_t
{
emlxs_port_t *port =
KM_NOSLEEP))) {
"fct_send_els_rsp: Unable to allocate packet.");
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_FAILURE);
}
pkt->pkt_timeout =
/* Build the fc header */
/* Copy the resp payload to pkt_cmd buffer */
/* mutex_exit(&cmd_sbp->fct_mtx); */
"fct_send_els_rsp: Unable to send packet.");
/* Reacquire ownership of the fct_cmd */
if (rval) {
"fct_send_els_rsp: "
"Unable to reacquire fct_cmd.");
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_FAILURE);
}
return (FCT_SUCCESS);
} /* emlxs_fct_send_els_rsp() */
/* COMSTAR ENTER POINT (INDIRECT) */
static fct_status_t
{
emlxs_port_t *port =
"fct_send_ct_cmd: Unable to allocate packet.");
return (FCT_BUSY);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
pkt->pkt_timeout =
/* Build the fc header */
/* Copy the cmd payload */
/* mutex_exit(&cmd_sbp->fct_mtx); */
"fct_send_ct_cmd: Unable to send packet.");
/* Reacquire ownership of the fct_cmd */
if (rval) {
"fct_send_ct_cmd: "
"Unable to reacquire fct_cmd.");
return (rval);
}
/* mutex_enter(&cmd_sbp->fct_mtx); */
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_BUSY);
}
return (FCT_SUCCESS);
} /* emlxs_fct_send_ct_cmd() */
/* cmd_sbp->fct_mtx must be held to enter */
static uint32_t
{
/* Check the transmit queue */
/* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */
if (pkt) {
goto done;
}
} else {
}
if (pkt_flags & PACKET_IN_TXQ) {
/* Find it on the queue */
found = 0;
/* Search the priority queue */
while (next) {
/* Remove it */
if (prev) {
}
(void *)iocbq) {
(void *)prev;
}
(void *)iocbq) {
q_first =
}
found = 1;
break;
}
}
} else {
/* Search the normal queue */
while (next) {
/* Remove it */
if (prev) {
}
(void *)iocbq) {
(void *)prev;
}
(void *)iocbq) {
}
found = 1;
break;
}
}
}
if (!found) {
goto done;
}
/* Check if node still needs servicing */
/*
* If this is the base node, don't shift the pointers
*/
/* We want to drain the base node before moving on */
/* Shift channel queue pointers to next node */
}
} else {
/* Remove node from channel queue */
/* If this is the last node on list */
} else {
/* Remove node from head */
}
/* Clear node */
}
/* The IOCB points to iocb_sbp (no packet) or a sbp (packet) */
} else {
}
if (pkt) {
}
return (1);
}
done:
return (0);
} /* emlxs_fct_pkt_abort_txq() */
/* COMSTAR ENTER POINT */
/* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */
/* FCT_SUCCESS indicates abort will occur asyncronously */
static fct_status_t
{
top:
/* Sanity check */
"fct_abort: Bad fct_cmd=%p.", fct_cmd);
return (FCT_NOT_FOUND);
}
"fct_abort: Pkt invalid. cmd_sbp=%p",
cmd_sbp);
return (FCT_NOT_FOUND);
}
if (mutex_tryenter(fct_mtx) == 0) {
/*
* This code path handles a race condition if
* an IO completes, in emlxs_fct_handle_fcp_event(),
* and we get an abort at the same time.
*/
goto top;
}
/* At this point, we have entered the mutex */
/* Sanity check */
"fct_abort: Bad fct_cmd=%p.", fct_cmd);
return (FCT_NOT_FOUND);
}
"fct_abort: Pkt invalid. cmd_sbp=%p",
cmd_sbp);
return (FCT_NOT_FOUND);
}
"fct_abort: hbastate=%x. "
"xid=%x,%x cmd_sbp=%p fctstate=%d flags=%x,%x,%x",
/* If Abort is already in progress */
return (FCT_SUCCESS);
}
if (flags & FCT_IOF_FORCE_FCA_DONE) {
fct_cmd->cmd_handle = 0;
}
/* These are currently owned by COMSTAR. */
/* They were last processed by emlxs_fct_cmd_post() */
/* We have NO exchange resources associated with this IO. */
case EMLXS_FCT_OWNED:
goto abort_done;
/* These are on the unsol waitQ in the driver */
case EMLXS_FCT_CMD_WAITQ:
/* Find and remove it */
while (cmd_sbp2) {
/* Remove it */
if (prev) {
}
}
}
break;
}
}
/*FALLTHROUGH*/
/* These are currently owned by COMSTAR. */
/* They were last processed by emlxs_fct_cmd_post() */
/* We have residual exchange resources associated with this IO */
case EMLXS_FCT_CMD_POSTED:
case FCT_CMD_FCP_XCHG: /* Unsol */
break;
case FCT_CMD_RCVD_ELS: /* Unsol */
break;
}
goto abort_done;
/* These are active in the driver */
/* They were last processed by emlxs_fct_cmd_release() */
case EMLXS_FCT_RSP_PENDING:
case EMLXS_FCT_REQ_PENDING:
case EMLXS_FCT_REG_PENDING:
case EMLXS_FCT_DATA_PENDING:
case EMLXS_FCT_STATUS_PENDING:
/* Abort anything pending */
}
goto abort_done;
}
/* If we're not online, then all IO will be flushed anyway */
"fct_abort: Not online. fct_cmd=%p.",
fct_cmd);
/* mutex_exit(&cmd_sbp->fct_mtx); */
/* The cmd will be aborted on the */
/* next emlxs_fct_cmd_acquire */
/* because EMLXS_FCT_ABORT_INP is set. */
break;
}
/* Try to send abort request */
"fct_abort: Unable to allocate packet. "
"fct_cmd=%p",
fct_cmd);
/* mutex_exit(&cmd_sbp->fct_mtx); */
/* The cmd will be aborted on the */
/* next emlxs_fct_cmd_acquire anyway */
/* because EMLXS_FCT_ABORT_INP is set. */
break;
}
pkt->pkt_timeout =
/* Build the fc header */
/* Make sure xrip is setup */
"fct_abort: "
"Unable to acquire xri. (xid:%x,%x)",
return (FCT_NOT_FOUND);
}
}
/* Now disassociate the sbp / pkt from the fct_cmd */
"fct_abort: ABORT: %p xid:%x,%x",
} else {
"fct_abort: CLOSE: %p xid:%x,%x",
}
/* mutex_exit(&cmd_sbp->fct_mtx); */
"fct_abort: Unable to send abort packet.");
/* The cmd will be aborted on the */
/* next emlxs_fct_cmd_acquire anyway */
/* because EMLXS_FCT_ABORT_INP is set. */
}
break;
default:
"fct_abort: Unexpected fct_state. "
"fct_cmd=%p state=%d",
/* mutex_exit(&cmd_sbp->fct_mtx); */
/* The cmd will be aborted on the */
/* next emlxs_fct_cmd_acquire anyway */
/* because EMLXS_FCT_ABORT_INP is set. */
} /* switch */
return (FCT_SUCCESS);
/* mutex_exit(&cmd_sbp->fct_mtx); */
return (FCT_ABORT_SUCCESS);
} /* emlxs_fct_abort() */
extern void
{
#ifdef FCT_API_TRACE
"fct_link_up port %p fct flags x%x",
#endif /* FCT_API_TRACE */
"fct_link_up event.");
#ifdef FCT_API_TRACE
"fct_handle_event LINK_UP");
#endif /* FCT_API_TRACE */
0, 0);
"fct_link_up event. FCT port offline (%x). "
"Disable link.",
/* Take link down and hold it down */
} else {
"fct_link_up event. FCT port offline (%x).",
}
} else {
}
return;
} /* emlxs_fct_link_up() */
extern void
{
#ifdef FCT_API_TRACE
"fct_link_down port %p fct flags x%x",
#endif /* FCT_API_TRACE */
"fct_link_down event.");
#ifdef FCT_API_TRACE
"fct_handle_event LINK_DOWN");
#endif /* FCT_API_TRACE */
0, 0);
} else {
}
return;
} /* emlxs_fct_link_down() */
void
{
return;
}
"Aborting FCT exchange: xid=%x", rxid);
/* We have no way to abort unsolicited exchanges */
/* that we have not responded to at this time */
/* So we will return for now */
return;
}
}
/* Create the abort IOCB */
} else {
}
if (iocbq) {
"Aborting FCT exchange: xid=%x iotag=%d", rxid,
}
} /* emlxs_abort_fct_exchange() */
extern uint32_t
{
return (0);
}
#ifdef FCT_API_TRACE
"stmf_alloc:%p iotag=%d phys %p virt %p sz %d",
#endif /* FCT_API_TRACE */
"emlxs_fct_stmf_alloc: alloc failed.");
return (1);
}
return (0);
} /* emlxs_fct_stmf_alloc() */
/* ARGSUSED */
extern void
{
#ifdef FCT_API_TRACE
#endif /* FCT_API_TRACE */
return;
}
return;
}
#ifdef FCT_API_TRACE
"stmf_free:%p iotag=%d",
#endif /* FCT_API_TRACE */
return;
} /* emlxs_fct_stmf_free() */
static void
{
char buf[32];
int i;
int j;
int fct_memseg_cnt = 0;
int numblks;
int memsize;
uint32_t fct_memseg_size = 0;
port->fct_memseg_cnt = 0;
/* Check for the per adapter setting */
/* Check for the global setting */
cnt = 0;
}
goto default_config;
}
if (!fct_memseg) {
"Unable to alloc fct_memseg. cnt=%d. "
"Trying default config.",
cnt);
goto default_config;
}
for (i = 0; i < cnt; i++) {
if (datap == 0) {
break;
}
datap++;
}
datap++;
}
datap++;
}
datap++;
}
/* Check for a bad entry */
"fct-bufpool: Entry %d:%d. Invalid.",
continue;
}
"fct-bufpool: Entry:%d %d:%d",
}
if (!fct_memseg_cnt) {
fct_memseg_size = 0;
fct_memseg = NULL;
}
/* If buffer list is empty, setup defaults */
if (!fct_memseg) {
if (!fct_memseg) {
"Unable to alloc default port buffer pool. "
"fct_memseg_cnt=%d",
cnt);
return;
}
i = 0;
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
if (numblks) {
}
fct_memseg_cnt = i;
}
sizeof (emlxs_memseg_t)), KM_SLEEP);
if (!port->fct_memseg) {
"Unable to alloc port buffer pool. fct_memseg_cnt=%d",
return;
}
/* Initalize port bucket list */
/* Sort the entries smallest to largest */
for (i = 0; i < fct_memseg_cnt; i++, seg++) {
/* Find next smallest buffer */
for (j = 0; j < fct_memseg_cnt; j++, current++) {
if (current->fc_memsize == 0) {
continue;
}
continue;
}
}
}
/* Save next entry */
next->fc_memsize = 0;
next->fc_numblks = 0;
}
/* Complete the initialization */
/* seg->fc_memsize = ; Already setup */
/* seg->fc_numblks = ; Already setup */
seg->fc_numblks = 0;
}
return;
} /* emlxs_fct_memseg_init() */
{
int32_t i;
/* Initialize the fct memseg list */
"fct_dmem_init: fct_memseg list is empty.");
return (FCT_FAILURE);
}
/* Create the DMA buffer pools */
"%s: count=%d size=%d flags=%x lo=%d hi=%d",
seg->fc_hi_water);
}
}
return (FCT_SUCCESS);
} /* emlxs_fct_dmem_init */
void
{
int32_t i;
"fct_dmem_fini: fct_memseg list is empty.");
return;
}
/* Destroy the dmem buffer pools */
}
/* Clear the segment space */
port->fct_memseg = 0;
port->fct_memseg_cnt = 0;
return;
} /* emlxs_fct_dmem_fini */
/* COMSTAR ENTER POINT */
/*ARGSUSED*/
static stmf_data_buf_t *
{
int i;
goto failed;
}
/* Check if our largest buffer is too small */
goto partial_alloc;
}
/* Find smallest available buffer >= size */
continue;
}
if (mp) {
goto success;
}
}
/* Find largest available buffer >= *pminsize */
goto failed;
}
if (mp) {
goto success;
}
}
"fct_dbuf_alloc:Failed. size=%d minsize=%d",
return (NULL);
/* Setup the data buffer */
#ifdef FCT_API_TRACE
"fct_dbuf_alloc:%p iotag=%d size=%d,%d",
#endif /* FCT_API_TRACE */
return (db);
} /* emlxs_fct_dbuf_alloc() */
/* COMSTAR ENTER POINT */
/*ARGSUSED*/
static void
{
if (!mp) {
"fct_dbuf_free:%p NULL mp found!",
db);
return;
}
#ifdef FCT_API_TRACE
"fct_dbuf_free:%p iotag=%d",
#endif /* FCT_API_TRACE */
} /* emlxs_fct_dbuf_free() */
static int
{
if (!mp) {
"fct_dbuf_dma_sync:%p NULL mp found!",
db);
return (0);
}
#ifdef FCT_API_TRACE
{
char buf[16];
"fct_dbuf_dma_sync:%p iotag=%d size=%d",
36, 0);
}
#endif /* FCT_API_TRACE */
#ifdef FMA_SUPPORT
!= DDI_FM_OK) {
"fct_dbuf_dma_sync:%p iotag=%d",
return (1);
}
#endif /* FMA_SUPPORT */
return (0);
} /* emlxs_fct_dbuf_dma_sync() */
#endif /* SFCT_SUPPORT */