Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ee5d43e authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.2.3 : NPIV bug fixes



NPIV bug fixes:
- Remove vport params on physical hba when npiv is disabled
- Implement new DA_ID CT command to remove vport information from
  the switch after delete. Some switches didn't clean this up unless
  the physical link dropped.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 57127f15
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -272,10 +272,16 @@ struct lpfc_vport {
#define FC_ABORT_DISCOVERY      0x8000	 /* we want to abort discovery */
#define FC_NDISC_ACTIVE         0x10000	 /* NPort discovery active */
#define FC_BYPASSED_MODE        0x20000	 /* NPort is in bypassed mode */
#define FC_RFF_NOT_SUPPORTED    0x40000	 /* RFF_ID was rejected by switch */
#define FC_VPORT_NEEDS_REG_VPI	0x80000  /* Needs to have its vpi registered */
#define FC_RSCN_DEFERRED	0x100000 /* A deferred RSCN being processed */

	uint32_t ct_flags;
#define FC_CT_RFF_ID		0x1	 /* RFF_ID accepted by switch */
#define FC_CT_RNN_ID		0x2	 /* RNN_ID accepted by switch */
#define FC_CT_RSNN_NN		0x4	 /* RSNN_NN accepted by switch */
#define FC_CT_RSPN_ID		0x8	 /* RSPN_ID accepted by switch */
#define FC_CT_RFT_ID		0x10	 /* RFT_ID accepted by switch */

	struct list_head fc_nodes;

	/* Keep counters for the number of entries in each list. */
@@ -344,6 +350,7 @@ struct lpfc_vport {
	uint32_t cfg_discovery_threads;
	uint32_t cfg_log_verbose;
	uint32_t cfg_max_luns;
	uint32_t cfg_enable_da_id;

	uint32_t dev_loss_tmo_changed;

+20 −61
Original line number Diff line number Diff line
@@ -1113,7 +1113,13 @@ MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:"
		 " 2 - select SLI-2 even on SLI-3 capable HBAs,"
		 " 3 - select SLI-3");

LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality");
int lpfc_enable_npiv = 0;
module_param(lpfc_enable_npiv, int, 0);
MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality");
lpfc_param_show(enable_npiv);
lpfc_param_init(enable_npiv, 0, 0, 1);
static CLASS_DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
			 lpfc_enable_npiv_show, NULL);

/*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1258,6 +1264,13 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff,
		       "Verbose logging bit-mask");

/*
# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
# objects that have been registered with the nameserver after login.
*/
LPFC_VPORT_ATTR_R(enable_da_id, 0, 0, 1,
		  "Deregister nameserver objects before LOGO");

/*
# lun_queue_depth:  This parameter is used to limit the number of outstanding
# commands per FCP LUN. Value range is [1,128]. Default value is 30.
@@ -1564,6 +1577,7 @@ struct class_device_attribute *lpfc_vport_attrs[] = {
	&class_device_attr_lpfc_max_luns,
	&class_device_attr_nport_evt_cnt,
	&class_device_attr_npiv_info,
	&class_device_attr_lpfc_enable_da_id,
	NULL,
};

@@ -2349,69 +2363,13 @@ struct fc_function_template lpfc_transport_functions = {
	.dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
	.terminate_rport_io = lpfc_terminate_rport_io,

	.vport_create = lpfc_vport_create,
	.vport_delete = lpfc_vport_delete,
	/* Vport fields are filled in at runtime based on enable_npiv */
	.vport_create = NULL,
	.vport_delete = NULL,
	.vport_disable = NULL,
	.dd_fcvport_size = sizeof(struct lpfc_vport *),
};

struct fc_function_template lpfc_vport_transport_functions = {
	/* fixed attributes the driver supports */
	.show_host_node_name = 1,
	.show_host_port_name = 1,
	.show_host_supported_classes = 1,
	.show_host_supported_fc4s = 1,
	.show_host_supported_speeds = 1,
	.show_host_maxframe_size = 1,

	/* dynamic attributes the driver supports */
	.get_host_port_id = lpfc_get_host_port_id,
	.show_host_port_id = 1,

	.get_host_port_type = lpfc_get_host_port_type,
	.show_host_port_type = 1,

	.get_host_port_state = lpfc_get_host_port_state,
	.show_host_port_state = 1,

	/* active_fc4s is shown but doesn't change (thus no get function) */
	.show_host_active_fc4s = 1,

	.get_host_speed = lpfc_get_host_speed,
	.show_host_speed = 1,

	.get_host_fabric_name = lpfc_get_host_fabric_name,
	.show_host_fabric_name = 1,

	/*
	 * The LPFC driver treats linkdown handling as target loss events
	 * so there are no sysfs handlers for link_down_tmo.
	 */

	.get_fc_host_stats = lpfc_get_stats,
	.reset_fc_host_stats = lpfc_reset_stats,

	.dd_fcrport_size = sizeof(struct lpfc_rport_data),
	.show_rport_maxframe_size = 1,
	.show_rport_supported_classes = 1,

	.set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
	.show_rport_dev_loss_tmo = 1,

	.get_starget_port_id  = lpfc_get_starget_port_id,
	.show_starget_port_id = 1,

	.get_starget_node_name = lpfc_get_starget_node_name,
	.show_starget_node_name = 1,

	.get_starget_port_name = lpfc_get_starget_port_name,
	.show_starget_port_name = 1,

	.dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
	.terminate_rport_io = lpfc_terminate_rport_io,

	.vport_disable = lpfc_vport_disable,
};

void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
@@ -2460,5 +2418,6 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
	lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
	lpfc_max_luns_init(vport, lpfc_max_luns);
	lpfc_scan_down_init(vport, lpfc_scan_down);
	lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
	return;
}
+1 −1
Original line number Diff line number Diff line
@@ -260,8 +260,8 @@ extern struct class_device_attribute *lpfc_vport_attrs[];
extern struct scsi_host_template lpfc_template;
extern struct scsi_host_template lpfc_vport_template;
extern struct fc_function_template lpfc_transport_functions;
extern struct fc_function_template lpfc_vport_transport_functions;
extern int lpfc_sli_mode;
extern int lpfc_enable_npiv;

int  lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
void lpfc_terminate_rport_io(struct fc_rport *);
+64 −12
Original line number Diff line number Diff line
@@ -458,7 +458,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
			    ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
			     vport->cfg_peer_port_login)) {
				if ((vport->port_type != LPFC_NPIV_PORT) ||
				    (vport->fc_flag & FC_RFF_NOT_SUPPORTED) ||
				    (!vport->ct_flags & FC_CT_RFF_ID) ||
				    (!vport->cfg_restrict_login)) {
					ndlp = lpfc_setup_disc_node(vport, Did);
					if (ndlp) {
@@ -778,7 +778,7 @@ out:


static void
lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	     struct lpfc_iocbq *rspiocb)
{
	struct lpfc_vport *vport = cmdiocb->vport;
@@ -809,7 +809,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,

	/* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
			 "0209 RFT request completes, latt %d, "
			 "0209 CT Request completes, latt %d, "
			 "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
			 latt, irsp->ulpStatus,
			 CTrsp->CommandResponse.bits.CmdRsp,
@@ -847,11 +847,29 @@ out:
	return;
}

static void
lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			struct lpfc_iocbq *rspiocb)
{
	IOCB_t *irsp = &rspiocb->iocb;
	struct lpfc_vport *vport = cmdiocb->vport;

	if (irsp->ulpStatus == IOSTAT_SUCCESS)
		vport->ct_flags |= FC_CT_RFT_ID;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

static void
lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			struct lpfc_iocbq *rspiocb)
{
	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
	IOCB_t *irsp = &rspiocb->iocb;
	struct lpfc_vport *vport = cmdiocb->vport;

	if (irsp->ulpStatus == IOSTAT_SUCCESS)
		vport->ct_flags |= FC_CT_RNN_ID;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

@@ -859,7 +877,12 @@ static void
lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			 struct lpfc_iocbq *rspiocb)
{
	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
	IOCB_t *irsp = &rspiocb->iocb;
	struct lpfc_vport *vport = cmdiocb->vport;

	if (irsp->ulpStatus == IOSTAT_SUCCESS)
		vport->ct_flags |= FC_CT_RSPN_ID;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

@@ -867,7 +890,24 @@ static void
lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			 struct lpfc_iocbq *rspiocb)
{
	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
	IOCB_t *irsp = &rspiocb->iocb;
	struct lpfc_vport *vport = cmdiocb->vport;

	if (irsp->ulpStatus == IOSTAT_SUCCESS)
		vport->ct_flags |= FC_CT_RSNN_NN;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

static void
lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 struct lpfc_iocbq *rspiocb)
{
	struct lpfc_vport *vport = cmdiocb->vport;

	/* even if it fails we will act as though it succeeded. */
	vport->ct_flags = 0;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

@@ -878,10 +918,9 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	IOCB_t *irsp = &rspiocb->iocb;
	struct lpfc_vport *vport = cmdiocb->vport;

	if (irsp->ulpStatus != IOSTAT_SUCCESS)
	    vport->fc_flag |= FC_RFF_NOT_SUPPORTED;

	lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb);
	if (irsp->ulpStatus == IOSTAT_SUCCESS)
		vport->ct_flags |= FC_CT_RFF_ID;
	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
	return;
}

@@ -1001,6 +1040,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_RSNN_NN)
		bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_DA_ID)
		bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
	else if (cmdcode == SLI_CTNS_RFF_ID)
		bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
	else
@@ -1034,6 +1075,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		break;

	case SLI_CTNS_RFT_ID:
		vport->ct_flags &= ~FC_CT_RFT_ID;
		CtReq->CommandResponse.bits.CmdRsp =
		    be16_to_cpu(SLI_CTNS_RFT_ID);
		CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1042,6 +1084,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		break;

	case SLI_CTNS_RNN_ID:
		vport->ct_flags &= ~FC_CT_RNN_ID;
		CtReq->CommandResponse.bits.CmdRsp =
		    be16_to_cpu(SLI_CTNS_RNN_ID);
		CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1051,6 +1094,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		break;

	case SLI_CTNS_RSPN_ID:
		vport->ct_flags &= ~FC_CT_RSPN_ID;
		CtReq->CommandResponse.bits.CmdRsp =
		    be16_to_cpu(SLI_CTNS_RSPN_ID);
		CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID);
@@ -1061,6 +1105,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
		cmpl = lpfc_cmpl_ct_cmd_rspn_id;
		break;
	case SLI_CTNS_RSNN_NN:
		vport->ct_flags &= ~FC_CT_RSNN_NN;
		CtReq->CommandResponse.bits.CmdRsp =
		    be16_to_cpu(SLI_CTNS_RSNN_NN);
		memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
@@ -1071,8 +1116,15 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
			CtReq->un.rsnn.symbname, size);
		cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
		break;
	case SLI_CTNS_DA_ID:
		/* Implement DA_ID Nameserver request */
		CtReq->CommandResponse.bits.CmdRsp =
			be16_to_cpu(SLI_CTNS_DA_ID);
		CtReq->un.da_id.port_id = be32_to_cpu(vport->fc_myDID);
		cmpl = lpfc_cmpl_ct_cmd_da_id;
		break;
	case SLI_CTNS_RFF_ID:
		vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED;
		vport->ct_flags &= ~FC_CT_RFF_ID;
		CtReq->CommandResponse.bits.CmdRsp =
		    be16_to_cpu(SLI_CTNS_RFF_ID);
		CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);;
+5 −0
Original line number Diff line number Diff line
@@ -139,6 +139,9 @@ struct lpfc_sli_ct_request {
			uint8_t len;
			uint8_t symbname[255];
		} rsnn;
		struct da_id { /* For DA_ID requests */
			uint32_t port_id;
		} da_id;
		struct rspn {	/* For RSPN_ID requests */
			uint32_t PortId;
			uint8_t len;
@@ -177,6 +180,8 @@ struct lpfc_sli_ct_request {
			   sizeof(struct rnn))
#define  RSNN_REQUEST_SZ  (offsetof(struct lpfc_sli_ct_request, un) + \
			   sizeof(struct rsnn))
#define DA_ID_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
			  sizeof(struct da_id))
#define  RSPN_REQUEST_SZ  (offsetof(struct lpfc_sli_ct_request, un) + \
			   sizeof(struct rspn))

Loading