emlxs_els.c revision 291a2b48b9adcd7b3666c34e80ba6411929afe7f
/*
* 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
*/
/*
* Copyright 2009 Emulex. All rights reserved.
* Use is subject to License terms.
*/
#include <emlxs.h>
/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
/* Routine Declaration - Local */
/* End Routine Declaration - Local */
/*
* emlxs_els_handle_event
*
* Description: Process an ELS Response Ring cmpl
*
*/
extern int
{
if (!sbp) {
/*
* completion with missing xmit command
*/
"iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
return (1);
}
"Not ELS ring: ring=%d iocbq=%p cmd=0x%x iotag=0x%x "
return (1);
}
/* Check if a response buffer was provided */
if (pkt->pkt_rsplen) {
}
switch (iocb->ulpCommand) {
/*
* ELS Reply completion
*/
case CMD_XMIT_ELS_RSP_CX:
case CMD_XMIT_ELS_RSP64_CX:
if (command == ELS_CMD_ACC) {
} else {
}
break;
/*
* ELS command completion
*/
case CMD_ELS_REQUEST_CR:
case CMD_ELS_REQUEST64_CR:
case CMD_ELS_REQUEST_CX:
case CMD_ELS_REQUEST64_CX:
/*
* ULP patch - ULP expects
* resp_resid = 0 on success
*/
pkt->pkt_resp_resid = 0;
}
switch (command) {
case ELS_CMD_FDISC: /* Fabric login */
break;
case ELS_CMD_FLOGI: /* Fabric login */
break;
case ELS_CMD_PLOGI: /* NPort login */
break;
case ELS_CMD_ADISC: /* Adisc */
break;
case ELS_CMD_LOGO: /* Logout */
break;
case ELS_CMD_PRLI: /* Process Log In */
break;
default:
&emlxs_els_completion_msg, "%s: did=%x",
break;
}
} else {
/* Look for LS_REJECT */
#ifdef SAN_DIAG_SUPPORT
if (ndlp) {
}
#endif
"%s Rejected: did=%x rsn=%x exp=%x",
"%s: did=%x Local Reject. %s",
} else {
"%s: did=%x %s (%02x%02x%02x%02x)",
}
switch (command) {
case ELS_CMD_PLOGI: /* NPort login failed */
/* Open the node again */
#ifdef DHCHAP_SUPPORT
}
#endif /* DHCHAP_SUPPORT */
}
break;
case ELS_CMD_PRLI: /* Process Log In failed */
/* Open the node again */
}
break;
case ELS_CMD_FDISC: /* Fabric login */
case ELS_CMD_FLOGI: /* Fabric login */
/* This will cause ULP to retry */
/* FLOGI requests */
#ifdef DHCHAP_SUPPORT
}
#endif /* DHCHAP_SUPPORT */
}
break;
default:
break;
}
}
break;
default:
break;
} /* switch(iocb->ulpCommand) */
return (0);
} /* emlxs_els_handle_event() */
extern int
{
switch (cmd_code) {
case ELS_CMD_RSCN:
break;
case ELS_CMD_FLOGI:
break;
case ELS_CMD_PLOGI:
break;
case ELS_CMD_PRLI:
break;
case ELS_CMD_PRLO:
break;
case ELS_CMD_LOGO:
break;
case ELS_CMD_ADISC:
break;
case ELS_CMD_AUTH:
break;
default:
break;
}
return (0);
} /* emlxs_els_handle_unsol_req() */
static void
{
char buffer[64];
uint32_t i;
/* Save our new port ID */
/* Save E_D_TOV ticks in nanoseconds */
} else {
}
/* Save R_A_TOV ticks */
/*
* If we are a N-port connected to a Fabric,
* fixup sparam's so logins to devices on remote
* loops work.
*/
/* Set this bit in all the port sparam copies */
for (i = 0; i < MAX_VPORTS; i++) {
continue;
}
}
}
#ifdef NPIV_SUPPORT
/*
* PATCH: for NPIV support on
* Brocade switch firmware 5.10b
*/
}
}
} else {
}
} else {
}
#else
buffer[0] = 0;
#endif /* NPIV_SUPPORT */
/* Save the fabric service parameters */
sizeof (SERV_PARM));
#ifdef DHCHAP_SUPPORT
} else {
}
#endif /* DHCHAP_SUPPORT */
/* Update our service parms */
MBX_NOWAIT, 0) != MBX_BUSY) {
}
}
/* Preset the state for the reg_did */
/* Deferred completion of this pkt until */
/* login is complete */
return;
}
IOERR_NO_RESOURCES, 1);
} else { /* No switch */
/* Save E_D_TOV ticks in nanoseconds */
} else {
}
/* Save R_A_TOV ticks */
#ifdef NPIV_SUPPORT
#else
#endif /* NPIV_SUPPORT */
/* Clear the fabric service parameters */
}
return;
} /* emlxs_handle_sol_flogi() */
static void
{
char buffer[64];
/* Save our new port ID */
/* Save the fabric service parameters */
buffer[0] = 0;
#ifdef DHCHAP_SUPPORT
} else {
}
#endif /* DHCHAP_SUPPORT */
/* Update our service parms */
0) != MBX_BUSY) {
}
}
/* Preset the state for the reg_did */
/*
* Deferred completion of this pkt until login is complete
*/
return;
}
return;
} /* emlxs_handle_sol_fdisk() */
static void
{
char buffer[64];
buffer[0] = 0;
#ifdef DHCHAP_SUPPORT
} else {
}
#endif /* DHCHAP_SUPPORT */
/* Preset the pkt state for reg_did */
/*
* Do register login to Firmware before calling packet completion
*/
/*
* Deferred completion of this pkt until login is complete
*/
return;
}
/* Open the node again */
}
return;
} /* emlxs_handle_sol_plogi() */
static void
{
did);
/* Open the node again */
}
return;
} /* emlxs_handle_sol_adisc() */
static void
{
/* Check for FCP support */
/* Check for target */
if (npr->targetFunc) {
} else {
}
/* Check for initiator */
if (npr->initiatorFunc) {
} else {
}
/* If TRI support is not required then force */
/* the task_retry_id value to one */
task_retry_id = 1;
} else {
}
/* Check for FCP2 target support */
/* Retry and TaskRetryId bits are both required here */
} else {
}
}
/* Open the node again */
/*
* Report PRLI completion
*/
} else {
"PRLI: did=%x: Node not found. Failing.", did);
/*
* Report PRLI failed
*/
IOERR_INVALID_RPI, 1);
}
return;
} /* emlxs_handle_sol_prli() */
static void
{
did);
/* Close the node for any further normal IO */
/* Flush tx queues */
/* Flush chip queues */
}
return;
} /* emlxs_handle_sol_logo() */
/* ARGSUSED */
static void
{
/* Log the legacy rscn event for physical port only */
}
/* Log the vport rscn event for all ports */
"RSCN rcvd: sid=%x %d page(s): %08X, %08X. Rejecting.",
goto drop_it;
}
/*
* Setup frame header
*/
"RSCN: sid=%x %d page(s): %08X, %08X buffer=%p token=%x.", sid,
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
return;
} /* emlxs_handle_unsol_rscn() */
/* This is shared by FCT driver */
extern uint32_t
{
/* Check payload size */
"FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
return (1);
}
/* Save E_D_TOV ticks in nanoseconds */
} else {
}
/* Save R_A_TOV ticks */
buffer[0] = 0;
#ifdef NPIV_SUPPORT
#else
#endif /* NPIV_SUPPORT */
#ifdef DHCHAP_SUPPORT
} else {
}
#endif /* DHCHAP_SUPPORT */
/* Clear the fabric service parameters */
return (0);
} /* emlxs_process_unsol_flogi() */
/* ARGSUSED */
static void
{
char buffer[64];
buffer[0] = 0;
/* Perform processing of FLOGI payload */
return;
}
"FLOGI rcvd: sid=%x. Rejecting.", sid);
goto drop_it;
}
/*
* Setup unsolicited buffer and pass it up
*/
/*
* Setup frame header
*/
buffer);
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
return;
} /* emlxs_handle_unsol_flogi() */
/* This is shared by FCT driver */
extern uint32_t
{
"PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
return (1);
}
#ifdef NPIV_SUPPORT
if (sp->valid_vendor_version) {
}
/* If remote port is the virtual port, then reject it */
reject_it = 1;
}
/* If we are a virtual port and the remote device */
/* is not a switch, then reject it */
Fabric_DID_MASK)) {
reject_it = 1;
}
if (reject_it) {
"PLOGI rcvd: sid=%x. Restricted. Rejecting.",
sid);
/*
* We still need to do reg_did and unreg_did
* to free up rpi
*/
(IOCBQ *)1);
return (1);
}
}
#endif /* NPIV_SUPPORT */
#ifdef DHCHAP_SUPPORT
"PLOGI: sid=%x. FCSP disabled. Rejecting.", sid);
return (1);
}
} else {
}
#endif /* DHCHAP_SUPPORT */
/* Check if this was a point to point Plogi */
/* Save our new port ID */
/* Save E_D_TOV ticks in nanoseconds */
} else {
}
/* Save R_A_TOV ticks */
/* Update our service parms */
MBX_NOWAIT, 0) != MBX_BUSY) {
}
}
}
return (0);
} /* emlxs_process_unsol_plogi() */
/* ARGSUSED */
static void
{
char buffer[64];
buffer[0] = 0;
/* Perform processing of PLOGI payload */
return;
}
#ifdef SAN_DIAG_SUPPORT
#endif
"PLOGI rcvd: sid=%x. Rejecting.", sid);
goto drop_it;
}
/*
* Setup unsolicited buffer and pass it up
*/
/*
* Setup frame header
*/
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
/* Create a new node and defer callback */
/*
* Defer completion of this pkt until login is complete
*/
goto drop_it;
}
return;
} /* emlxs_handle_unsol_plogi() */
/* ARGSUSED */
static void
{
#ifndef ULP_PATCH3
#endif
"PRLI: sid=%x: Node not found. Rejecting.", sid);
/* Auto reply to PRLI's */
goto drop_it;
}
/* If node exists then save FCP2 support */
/* Check for FCP2 support */
/* Check for target */
if (npr->targetFunc) {
} else {
}
/* Check for initiator */
if (npr->initiatorFunc) {
} else {
}
/* Check for FCP2 target support */
} else {
}
}
#ifdef ULP_PATCH3
"PRLI: sid=%x. Accepting.", sid);
/* Auto reply to PRLI's */
#else
/* Tell ULP about it */
"PRLI rcvd: sid=%x. Rejecting.", sid);
goto drop_it;
}
/*
* Setup unsolicited buffer and pass it up
*/
/*
* Setup frame header
*/
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
#endif /* ULP_PATCH3 */
return;
} /* emlxs_handle_unsol_prli() */
/* ARGSUSED */
static void
{
#ifdef DHCHAP_SUPPORT
"AUTH: sid=%x: Node not found. Rejecting.", sid);
/* Auto reply to AUTH_ELS's */
goto drop_it;
}
#else
"AUTH: sid=%x: Rejecting.", sid);
#endif /* DHCAHP_SUPPORT */
return;
} /* emlxs_handle_unsol_auth() */
/* ARGSUSED */
static void
{
#ifdef SAN_DIAG_SUPPORT
#endif
#ifdef SAN_DIAG_SUPPORT
if (ndlp) {
}
#endif
"ADISC: sid=%x: Accepting.", sid);
return;
} /* emlxs_handle_unsol_adisc() */
/* ARGSUSED */
static void
{
#ifndef ULP_PATCH4
#endif
/* Get the node */
#ifdef SAN_DIAG_SUPPORT
if (ndlp) {
}
#endif
#ifdef ULP_PATCH4
#ifdef ULP_PATCH6
/* Check if this is a SCSI target */
/* This is a SCSI target */
/* If only one node is present, then we can */
/* conclude that we are direct attached to a target */
"PRLO: sid=%x. Accepting and reseting link.",
sid);
/* Send Acc */
ELS_CMD_PRLO, 0, 0);
/* Spawn a thread to reset the link */
goto drop_it;
}
/* Check if fabric is present */
/* Auto reply to PRLO */
"PRLO: sid=%x. Accepting and generating RSCN.",
sid);
/* Send Acc */
ELS_CMD_PRLO, 0, 0);
/* Generate an RSCN to wakeup ULP */
goto drop_it;
}
}
/* SCSI target */
#endif /* ULP_PATCH6 */
/* Auto reply to PRLO */
"PRLO: sid=%x. Accepting.", sid);
/* Send Acc */
goto drop_it;
#else /* !ULP_PATCH4 */
/* Tell ULP about it */
"PRLO recvd: sid=%x. Rejecting.", sid);
goto drop_it;
}
/*
* Setup unsolicited buffer and pass it up
*/
/*
* Setup frame header
*/
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
#endif /* ULP_PATCH4 */
return;
} /* emlxs_handle_unsol_prlo() */
/* ARGSUSED */
static void
{
uint32_t reply_sent = 0;
#ifdef SAN_DIAG_SUPPORT
if (ndlp) {
}
#endif
#ifdef ULP_PATCH6
/* Check if this is a SCSI target */
/* This is a SCSI target */
/* If only one node is present, then we can */
/* conclude that we are direct attached to a target */
"LOGO: sid=%x. Accepting and reseting link.",
sid);
ELS_CMD_LOGO, 0, 0);
/* Spawn a thread to reset the link */
goto drop_it;
}
/* Check if fabric node is present */
/* Send reply ourselves */
/* We will block all attempts */
/* for ULP to reply to a LOGO */
"LOGO: sid=%x. Accepting and generating RSCN.",
sid);
ELS_CMD_LOGO, 0, 0);
/* Generate an RSCN to wakeup ULP */
goto drop_it;
}
reply_sent = 1;
}
}
/* SCSI target */
#endif /* ULP_PATCH6 */
if (!reply_sent) {
"LOGO rcvd: sid=%x. Rejecting.", sid);
}
goto drop_it;
}
/* Setup unsolicited buffer and pass it up */
/* Setup frame header */
#ifdef ULP_PATCH2
if (!reply_sent) {
/* Send Acc */
/* Send reply ourselves because ULP */
/* doesn't always reply to these */
/* We will block all attempts for ULP to reply to a LOGO */
ELS_CMD_LOGO, 0, 0);
reply_sent = 1;
}
#else /* !ULP_PATCH2 */
if (!reply_sent) {
}
#endif /* ULP_PATCH2 */
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
/* Clear the RPI */
/*
* Deferred completion of this ubp
* until unreg login is complete
*/
return;
}
}
return;
} /* emlxs_handle_unsol_logo() */
/* ARGSUSED */
static void
{
sid);
goto drop_it;
}
/* Setup frame header */
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
return;
} /* emlxs_handle_unsol_gen_cmd() */
/* This handles the reply completions to unsolicited cmds */
/* ARGSUSED */
static void
{
switch (ucmd) {
case ELS_CMD_PLOGI:
case ELS_CMD_ADISC:
/* Open the node again */
}
break;
case ELS_CMD_PRLI:
/* Open the node again */
}
break;
}
return;
} /* emlxs_handle_acc() */
/* This handles the reply completions to unsolicited cmds */
/* ARGSUSED */
static void
{
switch (ucmd) {
case ELS_CMD_PLOGI:
/* Open the node again */
}
break;
case ELS_CMD_PRLI:
/* Open the node again */
}
break;
}
return;
} /* emlxs_handle_reject() */
/* ARGSUSED */
extern int32_t
{
switch (type) {
case ELS_CMD_ACC: /* Accept Response */
/* Allocate the pkt */
switch (type2) {
case ELS_CMD_FLOGI:
0, KM_NOSLEEP))) {
return (1);
}
break;
case ELS_CMD_ADISC:
KM_NOSLEEP))) {
return (1);
}
break;
case ELS_CMD_PRLI:
KM_NOSLEEP))) {
return (1);
}
break;
case ELS_CMD_PRLO:
KM_NOSLEEP))) {
return (1);
}
break;
case ELS_CMD_AUTH:
default:
0, 0, KM_NOSLEEP))) {
return (1);
}
}
/* Common initialization */
}
/* Build the fc header */
/*
* EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
* "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2),
* pkt->pkt_cmd_fhdr.ox_id);
*/
/* Build the command */
/* Build the payload */
switch (type2) {
case ELS_CMD_ADISC:
sizeof (NAME_TYPE));
sizeof (NAME_TYPE));
break;
case ELS_CMD_PRLI:
}
}
} else {
}
break;
case ELS_CMD_PRLO:
break;
} /* switch(type2) */
break;
case ELS_CMD_LS_RJT: /* reject response */
return (1);
}
}
/* Build the fc header */
/*
* EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
* "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2),
* pkt->pkt_cmd_fhdr.ox_id);
*/
/* Build the command */
break;
}
/* Free the pkt */
}
return (rval);
} /* emlxs_els_reply() */
#ifdef ULP_PATCH6
extern uint32_t
{
"RSCN create: sid=0xfffffd 1 page(s): %08X, 00000000. "
"Creation failed.", d_id);
return ((uint32_t)FC_FAILURE);
}
/* Simulate an RSCN payload */
page++;
#ifdef EMLXS_I386
/* Put payload in BE format */
#endif /* EMLXS_I386 */
"RSCN: sid=fffffd 1 page(s): %08X, 00000000 buffer=%p "
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
#endif /* EMLXS_MODREV2X */
return (FC_SUCCESS);
} /* emlxs_generate_rscn() */
#endif /* ULP_PATCH6 */
#ifdef MENLO_SUPPORT
extern int
{
if (!sbp) {
/*
* completion with missing xmit command
*/
"iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
return (1);
}
return (1);
}
/* Check if a response buffer was provided */
if (pkt->pkt_rsplen) {
}
switch (iocb->ulpCommand) {
/*
* MENLO Command completion
*/
case CMD_GEN_REQUEST64_CR:
case CMD_GEN_REQUEST64_CX:
#ifdef SLI3_SUPPORT
} else
#endif /* SLI3_SUPPORT */
{
}
"%s: %s rxid=0x%x",
iocb->ulpContext);
} else {
"%s: %s %s %s rxid=0x%x",
}
break;
default:
break;
} /* switch(iocb->ulpCommand) */
return (0);
} /* emlxs_menlo_handle_event() */
#endif /* MENLO_SUPPORT */
extern int
{
if (!sbp) {
/*
* completion with missing xmit command
*/
"iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
return (1);
}
return (1);
}
#ifdef DFC_SUPPORT
if (cmd_code == SLI_CT_LOOPBACK) {
}
#endif /* DFC_SUPPORT */
/* Check if a response buffer was provided */
if (pkt->pkt_rsplen) {
}
switch (iocb->ulpCommand) {
/*
* CT Reply completion
*/
case CMD_XMIT_SEQUENCE_CX:
case CMD_XMIT_SEQUENCE64_CX:
case 0xFC: /* Name server */
break;
case 0xFA: /* Managment server */
break;
case 0x0A: /* Emulex Remote server */
break;
default:
}
break;
/*
* CT Command completion
*/
case CMD_GEN_REQUEST64_CR:
case CMD_GEN_REQUEST64_CX:
#ifdef SLI3_SUPPORT
} else
#endif /* SLI3_SUPPORT */
{
}
/*
* EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
* "INFO: pkt_resid=%d %d %d %x", pkt->pkt_resp_resid,
* pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize,
* iocb->un.genreq64.bdl.bdeFlags);
*/
(rsp_code == SLI_CT_RESPONSE_FS_ACC)) {
/* ULP patch - ULP expects */
/* resp_resid = 0 on success */
pkt->pkt_resp_resid = 0;
}
case 0xFC: /* Name server */
"%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
#if (EMLXS_MODREV < EMLXS_MODREV4)
if (cmd_code == SLI_CTNS_RNN_ID) {
}
#endif /* < EMLXS_MODREV4 */
break;
case 0xFA: /* Managment server */
"%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
break;
case 0x0A: /* Emulex Remote server */
"%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
break;
default:
"%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
}
} else {
if (rsp_code == SLI_CT_RESPONSE_FS_RJT) {
"%s: Rejected. rsn=%x exp=%x",
case 0xFC: /* Name server */
"%s: %s %s",
break;
case 0xFA: /* Managment server */
"%s: %s %s",
break;
case 0x0A: /* Emulex Remote server */
"%s: %s %s",
break;
default:
"%s: %s %s",
}
} else {
case 0xFC: /* Name server */
"%s: %s (%02x%02x%02x%02x)",
break;
case 0xFA: /* Managment server */
"%s: %s (%02x%02x%02x%02x)",
break;
case 0x0A: /* Emulex Remote server */
"%s: %s (%02x%02x%02x%02x)",
break;
default:
"%s: %s (%02x%02x%02x%02x)",
}
}
}
break;
default:
break;
} /* switch(iocb->ulpCommand) */
return (0);
} /* emlxs_ct_handle_event() */
extern int
{
#ifdef DFC_SUPPORT
if (cmd_code == SLI_CT_LOOPBACK) {
int rval;
return (rval);
}
#endif /* DFC_SUPPORT */
case 0xFC: /* Name server */
break;
case 0xFA: /* Managment server */
break;
case 0x0A: /* Emulex Remote server */
break;
default:
}
iocb->ulpContext)) {
/* Abort the exchange */
}
return (0);
} /* emlxs_ct_handle_unsol_req() */
static void
{
sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) {
return;
}
/* Build the fc header */
/* Build the command */
/* Send the pkt later in another thread */
/* Free the pkt */
}
return;
} /* emlxs_send_rsnn() */
extern uint32_t
{
return (1);
}
/* Common initialization */
}
/* Build the fc header */
/* Build the command */
sizeof (SERV_PARM));
/* Free the pkt */
} else {
}
return (rval);
} /* emlxs_ub_send_login_acc */
extern void
{
return;
}
return;
}
/* Build the fc header */
/* Build the command */
8);
/* Send the pkt now */
/* Free the pkt */
}
return;
} /* emlxs_send_logo() */