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

Commit 3de2a653 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.2.2 : Attribute and Parameter splits for vport and physical port



 - Split attributes up into vport and non-vport attributes.
 - Move vport specific cfg params to vport

Many of the vport-specific behaviors were still global attributes
on the physical port. Move them to the vport itself.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 549e55cd
Loading
Loading
Loading
Loading
+19 −15
Original line number Original line Diff line number Diff line
@@ -338,6 +338,20 @@ struct lpfc_vport {
	struct lpfc_debugfs_trc *disc_trc;
	struct lpfc_debugfs_trc *disc_trc;
	atomic_t disc_trc_cnt;
	atomic_t disc_trc_cnt;
#endif
#endif
	/* Vport Config Parameters */
	uint32_t cfg_scan_down;
	uint32_t cfg_lun_queue_depth;
	uint32_t cfg_nodev_tmo;
	uint32_t cfg_devloss_tmo;
	uint32_t cfg_restrict_login;
	uint32_t cfg_peer_port_login;
	uint32_t cfg_fcp_class;
	uint32_t cfg_use_adisc;
	uint32_t cfg_fdmi_on;
	uint32_t cfg_discovery_threads;
	uint32_t cfg_max_luns;

	uint32_t dev_loss_tmo_changed;
};
};


struct hbq_s {
struct hbq_s {
@@ -413,28 +427,16 @@ struct lpfc_hba {
	uint8_t  wwpn[8];
	uint8_t  wwpn[8];
	uint32_t RandomData[7];
	uint32_t RandomData[7];


	uint32_t cfg_log_verbose;
	/* HBA Config Parameters */
	uint32_t cfg_lun_queue_depth;
	uint32_t cfg_nodev_tmo;
	uint32_t cfg_devloss_tmo;
	uint32_t cfg_hba_queue_depth;
	uint32_t cfg_peer_port_login;
	uint32_t cfg_vport_restrict_login;
	uint32_t cfg_npiv_enable;
	uint32_t cfg_fcp_class;
	uint32_t cfg_use_adisc;
	uint32_t cfg_ack0;
	uint32_t cfg_ack0;
	uint32_t cfg_npiv_enable;
	uint32_t cfg_topology;
	uint32_t cfg_topology;
	uint32_t cfg_scan_down;
	uint32_t cfg_link_speed;
	uint32_t cfg_link_speed;
	uint32_t cfg_cr_delay;
	uint32_t cfg_cr_delay;
	uint32_t cfg_cr_count;
	uint32_t cfg_cr_count;
	uint32_t cfg_multi_ring_support;
	uint32_t cfg_multi_ring_support;
	uint32_t cfg_multi_ring_rctl;
	uint32_t cfg_multi_ring_rctl;
	uint32_t cfg_multi_ring_type;
	uint32_t cfg_multi_ring_type;
	uint32_t cfg_fdmi_on;
	uint32_t cfg_discovery_threads;
	uint32_t cfg_max_luns;
	uint32_t cfg_poll;
	uint32_t cfg_poll;
	uint32_t cfg_poll_tmo;
	uint32_t cfg_poll_tmo;
	uint32_t cfg_use_msi;
	uint32_t cfg_use_msi;
@@ -442,8 +444,10 @@ struct lpfc_hba {
	uint32_t cfg_sg_dma_buf_size;
	uint32_t cfg_sg_dma_buf_size;
	uint64_t cfg_soft_wwnn;
	uint64_t cfg_soft_wwnn;
	uint64_t cfg_soft_wwpn;
	uint64_t cfg_soft_wwpn;
	uint32_t cfg_hba_queue_depth;


	uint32_t dev_loss_tmo_changed;
	/* Config paramters that should be in the vport */
	uint32_t cfg_log_verbose;


	lpfc_vpd_t vpd;		/* vital product data */
	lpfc_vpd_t vpd;		/* vital product data */


+266 −88
Original line number Original line Diff line number Diff line
@@ -734,6 +734,77 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
		return -EINVAL;\
		return -EINVAL;\
}
}


#define lpfc_vport_param_show(attr)	\
static ssize_t \
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
{ \
	struct Scsi_Host  *shost = class_to_shost(cdev);\
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
	int val = 0;\
	val = vport->cfg_##attr;\
	return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
}

#define lpfc_vport_param_hex_show(attr)	\
static ssize_t \
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
{ \
	struct Scsi_Host  *shost = class_to_shost(cdev);\
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
	int val = 0;\
	val = vport->cfg_##attr;\
	return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
}

#define lpfc_vport_param_init(attr, default, minval, maxval)	\
static int \
lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
{ \
	if (val >= minval && val <= maxval) {\
		vport->cfg_##attr = val;\
		return 0;\
	}\
	lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \
			"%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
			"allowed range is ["#minval", "#maxval"]\n", \
			vport->phba->brd_no, val); \
	vport->cfg_##attr = default;\
	return -EINVAL;\
}

#define lpfc_vport_param_set(attr, default, minval, maxval)	\
static int \
lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
{ \
	if (val >= minval && val <= maxval) {\
		vport->cfg_##attr = val;\
		return 0;\
	}\
	lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT, \
			"%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
			"allowed range is ["#minval", "#maxval"]\n", \
			vport->phba->brd_no, val); \
	return -EINVAL;\
}

#define lpfc_vport_param_store(attr)	\
static ssize_t \
lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
{ \
	struct Scsi_Host  *shost = class_to_shost(cdev);\
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
	int val=0;\
	if (!isdigit(buf[0]))\
		return -EINVAL;\
	if (sscanf(buf, "%i", &val) != 1)\
		return -EINVAL;\
	if (lpfc_##attr##_set(vport, val) == 0) \
		return strlen(buf);\
	else \
		return -EINVAL;\
}


#define LPFC_ATTR(name, defval, minval, maxval, desc) \
#define LPFC_ATTR(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
module_param(lpfc_##name, int, 0);\
@@ -778,6 +849,50 @@ lpfc_param_store(name)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
			 lpfc_##name##_show, lpfc_##name##_store)
			 lpfc_##name##_show, lpfc_##name##_store)


#define LPFC_VPORT_ATTR(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_vport_param_init(name, defval, minval, maxval)

#define LPFC_VPORT_ATTR_R(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_vport_param_show(name)\
lpfc_vport_param_init(name, defval, minval, maxval)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)

#define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_vport_param_show(name)\
lpfc_vport_param_init(name, defval, minval, maxval)\
lpfc_vport_param_set(name, defval, minval, maxval)\
lpfc_vport_param_store(name)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
			 lpfc_##name##_show, lpfc_##name##_store)

#define LPFC_VPORT_ATTR_HEX_R(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_vport_param_hex_show(name)\
lpfc_vport_param_init(name, defval, minval, maxval)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)

#define LPFC_VPORT_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_vport_param_hex_show(name)\
lpfc_vport_param_init(name, defval, minval, maxval)\
lpfc_vport_param_set(name, defval, minval, maxval)\
lpfc_vport_param_store(name)\
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
			 lpfc_##name##_show, lpfc_##name##_store)

static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
@@ -1019,53 +1134,48 @@ lpfc_nodev_tmo_show(struct class_device *cdev, char *buf)
{
{
	struct Scsi_Host  *shost = class_to_shost(cdev);
	struct Scsi_Host  *shost = class_to_shost(cdev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	int val = 0;
	int val = 0;
	val = phba->cfg_devloss_tmo;
	val = vport->cfg_devloss_tmo;
	return snprintf(buf, PAGE_SIZE, "%d\n",
	return snprintf(buf, PAGE_SIZE, "%d\n",	vport->cfg_devloss_tmo);
			phba->cfg_devloss_tmo);
}
}


static int
static int
lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
{
{
	static int warned;
	if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
	if (phba->cfg_devloss_tmo !=  LPFC_DEF_DEVLOSS_TMO) {
		vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
		phba->cfg_nodev_tmo = phba->cfg_devloss_tmo;
		if (val != LPFC_DEF_DEVLOSS_TMO)
		if (!warned && val != LPFC_DEF_DEVLOSS_TMO) {
			lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
			warned = 1;
					"%d (%d):0402 Ignoring nodev_tmo module"
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"%d:0402 Ignoring nodev_tmo module "
					" parameter because devloss_tmo is"
					" parameter because devloss_tmo is"
					" set.\n",
					" set.\n",
					phba->brd_no);
					vport->phba->brd_no, vport->vpi);
		}
		return 0;
		return 0;
	}
	}


	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
		phba->cfg_nodev_tmo = val;
		vport->cfg_nodev_tmo = val;
		phba->cfg_devloss_tmo = val;
		vport->cfg_devloss_tmo = val;
		return 0;
		return 0;
	}
	}
	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
	lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
			"%d:0400 lpfc_nodev_tmo attribute cannot be set to %d, "
			"%d (%d):0400 lpfc_nodev_tmo attribute cannot be set to"
			"allowed range is [%d, %d]\n",
			" %d, allowed range is [%d, %d]\n",
			phba->brd_no, val,
			vport->phba->brd_no, vport->vpi, val,
			LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
			LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
	phba->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
	vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
	return -EINVAL;
	return -EINVAL;
}
}


static void
static void
lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
{
{
	struct lpfc_vport **vports;
	struct lpfc_vport **vports;
	struct Scsi_Host  *shost;
	struct Scsi_Host  *shost;
	struct lpfc_nodelist  *ndlp;
	struct lpfc_nodelist  *ndlp;
	int i;
	int i;


	vports = lpfc_create_vport_work_array(phba);
	vports = lpfc_create_vport_work_array(vport->phba);
	if (vports != NULL)
	if (vports != NULL)
		for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
		for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
			shost = lpfc_shost_from_vport(vports[i]);
			shost = lpfc_shost_from_vport(vports[i]);
@@ -1074,40 +1184,38 @@ lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
					    nlp_listp)
					    nlp_listp)
			if (ndlp->rport)
			if (ndlp->rport)
				ndlp->rport->dev_loss_tmo =
				ndlp->rport->dev_loss_tmo =
						phba->cfg_devloss_tmo;
						vport->cfg_devloss_tmo;
			spin_unlock_irq(shost->host_lock);
			spin_unlock_irq(shost->host_lock);
		}
		}
	lpfc_destroy_vport_work_array(vports);
	lpfc_destroy_vport_work_array(vports);
}
}


static int
static int
lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
{
{
	if (phba->dev_loss_tmo_changed ||
	if (vport->dev_loss_tmo_changed ||
	    (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
	    (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
		lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
				"%d:0401 Ignoring change to nodev_tmo "
				"%d (%d):0401 Ignoring change to nodev_tmo "
				"because devloss_tmo is set.\n",
				"because devloss_tmo is set.\n",
				phba->brd_no);
				vport->phba->brd_no, vport->vpi);
		return 0;
		return 0;
	}
	}

	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
		phba->cfg_nodev_tmo = val;
		vport->cfg_nodev_tmo = val;
		phba->cfg_devloss_tmo = val;
		vport->cfg_devloss_tmo = val;
		lpfc_update_rport_devloss_tmo(phba);
		lpfc_update_rport_devloss_tmo(vport);
		return 0;
		return 0;
	}
	}

	lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			"%d (%d):0403 lpfc_nodev_tmo attribute cannot be set to"
			"%d:0403 lpfc_nodev_tmo attribute cannot be set to %d, "
			"%d, allowed range is [%d, %d]\n",
			"allowed range is [%d, %d]\n",
			vport->phba->brd_no, vport->vpi, val,
			phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
			LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
			LPFC_MAX_DEVLOSS_TMO);
	return -EINVAL;
	return -EINVAL;
}
}


lpfc_param_store(nodev_tmo)
lpfc_vport_param_store(nodev_tmo)


static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR,
static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR,
			 lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);
			 lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);
@@ -1121,29 +1229,29 @@ module_param(lpfc_devloss_tmo, int, 0);
MODULE_PARM_DESC(lpfc_devloss_tmo,
MODULE_PARM_DESC(lpfc_devloss_tmo,
		 "Seconds driver will hold I/O waiting "
		 "Seconds driver will hold I/O waiting "
		 "for a device to come back");
		 "for a device to come back");
lpfc_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
		      LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
		      LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
lpfc_param_show(devloss_tmo)
lpfc_vport_param_show(devloss_tmo)
static int
static int
lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
{
{
	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
	if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
		phba->cfg_nodev_tmo = val;
		vport->cfg_nodev_tmo = val;
		phba->cfg_devloss_tmo = val;
		vport->cfg_devloss_tmo = val;
		phba->dev_loss_tmo_changed = 1;
		vport->dev_loss_tmo_changed = 1;
		lpfc_update_rport_devloss_tmo(phba);
		lpfc_update_rport_devloss_tmo(vport);
		return 0;
		return 0;
	}
	}


	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
	lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
			"%d:0404 lpfc_devloss_tmo attribute cannot be set to"
			"%d:0404 lpfc_devloss_tmo attribute cannot be set to"
			" %d, allowed range is [%d, %d]\n",
			" %d, allowed range is [%d, %d]\n",
			phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
			vport->phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
			LPFC_MAX_DEVLOSS_TMO);
			LPFC_MAX_DEVLOSS_TMO);
	return -EINVAL;
	return -EINVAL;
}
}


lpfc_param_store(devloss_tmo)
lpfc_vport_param_store(devloss_tmo)
static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
	lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);
	lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);


@@ -1171,7 +1279,7 @@ LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
# lun_queue_depth:  This parameter is used to limit the number of outstanding
# 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.
# commands per FCP LUN. Value range is [1,128]. Default value is 30.
*/
*/
LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128,
		  "Max number of FCP commands we can queue to a specific LUN");
		  "Max number of FCP commands we can queue to a specific LUN");


/*
/*
@@ -1193,12 +1301,12 @@ LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
# are allowed to login to each other.
# are allowed to login to each other.
# Default value of this parameter is 0.
# Default value of this parameter is 0.
*/
*/
LPFC_ATTR_R(peer_port_login, 0, 0, 1,
LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
		  "Allow peer ports on the same physical port to login to each "
		  "Allow peer ports on the same physical port to login to each "
		  "other.");
		  "other.");


/*
/*
# vport_restrict_login:  This parameter allows/prevents logins
# restrict_login:  This parameter allows/prevents logins
# between Virtual Ports and remote initiators.
# between Virtual Ports and remote initiators.
# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
# other initiators and will attempt to PLOGI all remote ports.
# other initiators and will attempt to PLOGI all remote ports.
@@ -1208,8 +1316,56 @@ LPFC_ATTR_R(peer_port_login, 0, 0, 1,
# This parameter does not restrict logins to Fabric resident remote ports.
# This parameter does not restrict logins to Fabric resident remote ports.
# Default value of this parameter is 1.
# Default value of this parameter is 1.
*/
*/
LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1,
static int lpfc_restrict_login = 1;
module_param(lpfc_restrict_login, int, 0);
MODULE_PARM_DESC(lpfc_restrict_login,
		 "Restrict virtual ports login to remote initiators.");
		 "Restrict virtual ports login to remote initiators.");
lpfc_vport_param_show(restrict_login);

static int
lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
{
	if (val < 0 || val > 1) {
		lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
				"%d:0449 lpfc_restrict_login attribute cannot "
				"be set to %d, allowed range is [0, 1]\n",
				vport->phba->brd_no, val);
		vport->cfg_restrict_login = 1;
		return -EINVAL;
	}
	if (vport->port_type == LPFC_PHYSICAL_PORT) {
		vport->cfg_restrict_login = 0;
		return 0;
	}
	vport->cfg_restrict_login = val;
	return 0;
}

static int
lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
{
	if (val < 0 || val > 1) {
		lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
				"%d:0450 lpfc_restrict_login attribute cannot "
				"be set to %d, allowed range is [0, 1]\n",
				vport->phba->brd_no, val);
		vport->cfg_restrict_login = 1;
		return -EINVAL;
	}
	if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
		lpfc_printf_log(vport->phba, KERN_ERR, LOG_INIT,
				"%d:0468 lpfc_restrict_login must be 0 for "
				"Physical ports.\n",
				vport->phba->brd_no);
		vport->cfg_restrict_login = 0;
		return 0;
	}
	vport->cfg_restrict_login = val;
	return 0;
}
lpfc_vport_param_store(restrict_login);
static CLASS_DEVICE_ATTR(lpfc_restrict_login, S_IRUGO | S_IWUSR,
			 lpfc_restrict_login_show, lpfc_restrict_login_store);


/*
/*
# Some disk devices have a "select ID" or "select Target" capability.
# Some disk devices have a "select ID" or "select Target" capability.
@@ -1228,7 +1384,7 @@ LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1,
# and will not work across a fabric. Also this parameter will take
# and will not work across a fabric. Also this parameter will take
# effect only in the case when ALPA map is not available.)
# effect only in the case when ALPA map is not available.)
*/
*/
LPFC_ATTR_R(scan_down, 1, 0, 1,
LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
		  "Start scanning for devices from highest ALPA to lowest");
		  "Start scanning for devices from highest ALPA to lowest");


/*
/*
@@ -1260,14 +1416,14 @@ LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed");
# lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
# lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
# Value range is [2,3]. Default value is 3.
# Value range is [2,3]. Default value is 3.
*/
*/
LPFC_ATTR_R(fcp_class, 3, 2, 3,
LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
		  "Select Fibre Channel class of service for FCP sequences");
		  "Select Fibre Channel class of service for FCP sequences");


/*
/*
# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
# is [0,1]. Default value is 0.
# is [0,1]. Default value is 0.
*/
*/
LPFC_ATTR_RW(use_adisc, 0, 0, 1,
LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
		   "Use ADISC on rediscovery to authenticate FCP devices");
		   "Use ADISC on rediscovery to authenticate FCP devices");


/*
/*
@@ -1320,13 +1476,13 @@ LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1,
#       2 = support FDMI with attribute of hostname
#       2 = support FDMI with attribute of hostname
# Value range [0,2]. Default value is 0.
# Value range [0,2]. Default value is 0.
*/
*/
LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");


/*
/*
# Specifies the maximum number of ELS cmds we can have outstanding (for
# Specifies the maximum number of ELS cmds we can have outstanding (for
# discovery). Value range is [1,64]. Default value = 32.
# discovery). Value range is [1,64]. Default value = 32.
*/
*/
LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
		 "during discovery");
		 "during discovery");


/*
/*
@@ -1334,8 +1490,7 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
# Value range is [0,65535]. Default value is 255.
# Value range is [0,65535]. Default value is 255.
# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
*/
*/
LPFC_ATTR_R(max_luns, 255, 0, 65535,
LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN");
	     "Maximum allowed LUN");


/*
/*
# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
@@ -1372,7 +1527,6 @@ struct class_device_attribute *lpfc_hba_attrs[] = {
	&class_device_attr_lpfc_lun_queue_depth,
	&class_device_attr_lpfc_lun_queue_depth,
	&class_device_attr_lpfc_hba_queue_depth,
	&class_device_attr_lpfc_hba_queue_depth,
	&class_device_attr_lpfc_peer_port_login,
	&class_device_attr_lpfc_peer_port_login,
	&class_device_attr_lpfc_vport_restrict_login,
	&class_device_attr_lpfc_nodev_tmo,
	&class_device_attr_lpfc_nodev_tmo,
	&class_device_attr_lpfc_devloss_tmo,
	&class_device_attr_lpfc_devloss_tmo,
	&class_device_attr_lpfc_fcp_class,
	&class_device_attr_lpfc_fcp_class,
@@ -1409,6 +1563,29 @@ struct class_device_attribute *lpfc_hba_attrs[] = {
	NULL,
	NULL,
};
};


struct class_device_attribute *lpfc_vport_attrs[] = {
	&class_device_attr_info,
	&class_device_attr_state,
	&class_device_attr_num_discovered_ports,
	&class_device_attr_lpfc_drvr_version,

	&class_device_attr_lpfc_log_verbose,
	&class_device_attr_lpfc_lun_queue_depth,
	&class_device_attr_lpfc_nodev_tmo,
	&class_device_attr_lpfc_devloss_tmo,
	&class_device_attr_lpfc_hba_queue_depth,
	&class_device_attr_lpfc_peer_port_login,
	&class_device_attr_lpfc_restrict_login,
	&class_device_attr_lpfc_fcp_class,
	&class_device_attr_lpfc_use_adisc,
	&class_device_attr_lpfc_fdmi_on,
	&class_device_attr_lpfc_max_luns,
	&class_device_attr_nport_evt_cnt,
	&class_device_attr_management_version,
	&class_device_attr_npiv_info,
	NULL,
};

static ssize_t
static ssize_t
sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
		   char *buf, loff_t off, size_t count)
		   char *buf, loff_t off, size_t count)
@@ -2264,33 +2441,20 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
	lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
	lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
	lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
	lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
	lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
	lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
	lpfc_fcp_class_init(phba, lpfc_fcp_class);
	lpfc_use_adisc_init(phba, lpfc_use_adisc);
	lpfc_ack0_init(phba, lpfc_ack0);
	lpfc_ack0_init(phba, lpfc_ack0);
	lpfc_topology_init(phba, lpfc_topology);
	lpfc_topology_init(phba, lpfc_topology);
	lpfc_scan_down_init(phba, lpfc_scan_down);
	lpfc_link_speed_init(phba, lpfc_link_speed);
	lpfc_link_speed_init(phba, lpfc_link_speed);
	lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
	lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
	lpfc_max_luns_init(phba, lpfc_max_luns);
	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
	lpfc_peer_port_login_init(phba, lpfc_peer_port_login);
	lpfc_npiv_enable_init(phba, lpfc_npiv_enable);
	lpfc_npiv_enable_init(phba, lpfc_npiv_enable);
	lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login);
	lpfc_use_msi_init(phba, lpfc_use_msi);
	lpfc_use_msi_init(phba, lpfc_use_msi);
	lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
	lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
	phba->cfg_poll = lpfc_poll;
	phba->cfg_poll = lpfc_poll;
	phba->cfg_soft_wwnn = 0L;
	phba->cfg_soft_wwnn = 0L;
	phba->cfg_soft_wwpn = 0L;
	phba->cfg_soft_wwpn = 0L;

	/*
	/*
	 * The total number of segments is the configuration value plus 2
	 * The total number of segments is the configuration value plus 2
	 * since the IOCB need a command and response bde.
	 * since the IOCB need a command and response bde.
	 */
	 */
	phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;
	phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;

	/*
	/*
	 * Since the sg_tablesize is module parameter, the sg_dma_buf_size
	 * Since the sg_tablesize is module parameter, the sg_dma_buf_size
	 * used to create the sg_dma_buf_pool must be dynamically calculated
	 * used to create the sg_dma_buf_pool must be dynamically calculated
@@ -2298,9 +2462,23 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
	phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
			sizeof(struct fcp_rsp) +
			sizeof(struct fcp_rsp) +
			(phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
			(phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));


	lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
	lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
	return;
}


void
lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
{
	lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
	lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
	lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
	lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
	lpfc_restrict_login_init(vport, lpfc_restrict_login);
	lpfc_fcp_class_init(vport, lpfc_fcp_class);
	lpfc_use_adisc_init(vport, lpfc_use_adisc);
	lpfc_fdmi_on_init(vport, lpfc_fdmi_on);
	lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
	lpfc_max_luns_init(vport, lpfc_max_luns);
	lpfc_scan_down_init(vport, lpfc_scan_down);
	return;
	return;
}
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -250,10 +250,13 @@ const char* lpfc_info(struct Scsi_Host *);
int lpfc_scan_finished(struct Scsi_Host *, unsigned long);
int lpfc_scan_finished(struct Scsi_Host *, unsigned long);


void lpfc_get_cfgparam(struct lpfc_hba *);
void lpfc_get_cfgparam(struct lpfc_hba *);
void lpfc_get_vport_cfgparam(struct lpfc_vport *);
int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
void lpfc_free_sysfs_attr(struct lpfc_vport *);
void lpfc_free_sysfs_attr(struct lpfc_vport *);
extern struct class_device_attribute *lpfc_hba_attrs[];
extern struct class_device_attribute *lpfc_hba_attrs[];
extern struct class_device_attribute *lpfc_vport_attrs[];
extern struct scsi_host_template lpfc_template;
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_transport_functions;
extern struct fc_function_template lpfc_vport_transport_functions;
extern struct fc_function_template lpfc_vport_transport_functions;
extern int lpfc_sli_mode;
extern int lpfc_sli_mode;
@@ -262,7 +265,7 @@ int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
void lpfc_terminate_rport_io(struct fc_rport *);
void lpfc_terminate_rport_io(struct fc_rport *);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);


struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct fc_vport *);
struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *);
int  lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
int  lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *);
+3 −3
Original line number Original line Diff line number Diff line
@@ -451,10 +451,10 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
			 */
			 */
			if ((Did != vport->fc_myDID) &&
			if ((Did != vport->fc_myDID) &&
			    ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
			    ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
			     phba->cfg_peer_port_login)) {
			     vport->cfg_peer_port_login)) {
				if ((vport->port_type != LPFC_NPIV_PORT) ||
				if ((vport->port_type != LPFC_NPIV_PORT) ||
				    (vport->fc_flag & FC_RFF_NOT_SUPPORTED) ||
				    (vport->fc_flag & FC_RFF_NOT_SUPPORTED) ||
				    (!phba->cfg_vport_restrict_login)) {
				    (!vport->cfg_restrict_login)) {
					ndlp = lpfc_setup_disc_node(vport, Did);
					ndlp = lpfc_setup_disc_node(vport, Did);
					if (ndlp) {
					if (ndlp) {
						lpfc_debugfs_disc_trc(vport,
						lpfc_debugfs_disc_trc(vport,
@@ -1471,7 +1471,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
			pab->ab.EntryCnt++;
			pab->ab.EntryCnt++;
			size += FOURBYTES + len;
			size += FOURBYTES + len;


			if (phba->cfg_fdmi_on == 2) {
			if (vport->cfg_fdmi_on == 2) {
				/* #6 Port attribute entry */
				/* #6 Port attribute entry */
				ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
				ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
							  size);
							  size);
+5 −5
Original line number Original line Diff line number Diff line
@@ -518,7 +518,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		 * alpa map would take too long otherwise.
		 * alpa map would take too long otherwise.
		 */
		 */
		if (phba->alpa_map[0] == 0) {
		if (phba->alpa_map[0] == 0) {
			phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
			vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
		}
		}


		/* FLOGI failure */
		/* FLOGI failure */
@@ -2640,7 +2640,7 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport)
			sentadisc++;
			sentadisc++;
			vport->num_disc_nodes++;
			vport->num_disc_nodes++;
			if (vport->num_disc_nodes >=
			if (vport->num_disc_nodes >=
			    vport->phba->cfg_discovery_threads) {
			    vport->cfg_discovery_threads) {
				spin_lock_irq(shost->host_lock);
				spin_lock_irq(shost->host_lock);
				vport->fc_flag |= FC_NLP_MORE;
				vport->fc_flag |= FC_NLP_MORE;
				spin_unlock_irq(shost->host_lock);
				spin_unlock_irq(shost->host_lock);
@@ -2675,7 +2675,7 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
			sentplogi++;
			sentplogi++;
			vport->num_disc_nodes++;
			vport->num_disc_nodes++;
			if (vport->num_disc_nodes >=
			if (vport->num_disc_nodes >=
			    vport->phba->cfg_discovery_threads) {
			    vport->cfg_discovery_threads) {
				spin_lock_irq(shost->host_lock);
				spin_lock_irq(shost->host_lock);
				vport->fc_flag |= FC_NLP_MORE;
				vport->fc_flag |= FC_NLP_MORE;
				spin_unlock_irq(shost->host_lock);
				spin_unlock_irq(shost->host_lock);
@@ -2841,7 +2841,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
	 * just ACC and ignore it.
	 * just ACC and ignore it.
	 */
	 */
	if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
	if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
		!(phba->cfg_peer_port_login)) {
		!(vport->cfg_peer_port_login)) {
		i = payload_len;
		i = payload_len;
		datap = lp;
		datap = lp;
		while (i > 0) {
		while (i > 0) {
@@ -4170,7 +4170,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
		return;
		return;
	}
	}


	if (phba->cfg_fdmi_on) {
	if (vport->cfg_fdmi_on) {
		ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
		ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
					  GFP_KERNEL);
					  GFP_KERNEL);
		if (ndlp_fdmi) {
		if (ndlp_fdmi) {
Loading