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

[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
...@@ -338,6 +338,20 @@ struct lpfc_vport { ...@@ -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 { ...@@ -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 { ...@@ -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 */
......
...@@ -734,6 +734,77 @@ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ ...@@ -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)\ ...@@ -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) ...@@ -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, " parameter because devloss_tmo is"
"%d:0402 Ignoring nodev_tmo module "
"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) ...@@ -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); ...@@ -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,8 +1279,8 @@ LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); ...@@ -1171,8 +1279,8 @@ 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");
/* /*
# hba_queue_depth: This parameter is used to limit the number of outstanding # hba_queue_depth: This parameter is used to limit the number of outstanding
...@@ -1193,12 +1301,12 @@ LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, ...@@ -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, ...@@ -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;
"Restrict virtual ports login to remote initiators."); module_param(lpfc_restrict_login, int, 0);
MODULE_PARM_DESC(lpfc_restrict_login,
"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,8 +1384,8 @@ LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1, ...@@ -1228,8 +1384,8 @@ 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");
/* /*
# lpfc_topology: link topology for init link # lpfc_topology: link topology for init link
...@@ -1260,15 +1416,15 @@ LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed"); ...@@ -1260,15 +1416,15 @@ 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");
/* /*
# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
...@@ -1320,13 +1476,13 @@ LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1, ...@@ -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 " ...@@ -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[] = { ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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;
} }
...@@ -250,10 +250,13 @@ const char* lpfc_info(struct Scsi_Host *); ...@@ -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); ...@@ -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 *);
......
...@@ -451,10 +451,10 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) ...@@ -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) ...@@ -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);
......
...@@ -518,7 +518,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) {
......
...@@ -2200,7 +2200,7 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport) ...@@ -2200,7 +2200,7 @@ lpfc_disc_list_loopmap(struct lpfc_vport *vport)
/* If cfg_scan_down is set, start from highest /* If cfg_scan_down is set, start from highest
* ALPA (0xef) to lowest (0x1). * ALPA (0xef) to lowest (0x1).
*/ */
if (phba->cfg_scan_down) if (vport->cfg_scan_down)
index = j; index = j;
else else
index = FC_MAXLOOP - j - 1; index = FC_MAXLOOP - j - 1;
...@@ -2749,7 +2749,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -2749,7 +2749,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
* fdmi-on=2 (supporting RPA/hostnmae) * fdmi-on=2 (supporting RPA/hostnmae)
*/ */
if (phba->cfg_fdmi_on == 1) if (vport->cfg_fdmi_on == 1)
lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
else else
mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
......
...@@ -1524,13 +1524,18 @@ lpfc_scsi_free(struct lpfc_hba *phba) ...@@ -1524,13 +1524,18 @@ lpfc_scsi_free(struct lpfc_hba *phba)
} }
struct lpfc_vport * struct lpfc_vport *
lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
{ {
struct lpfc_vport *vport; struct lpfc_vport *vport;
struct Scsi_Host *shost; struct Scsi_Host *shost;
int error = 0; int error = 0;
shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport)); if (dev != &phba->pcidev->dev)
shost = scsi_host_alloc(&lpfc_vport_template,
sizeof(struct lpfc_vport));
else
shost = scsi_host_alloc(&lpfc_template,
sizeof(struct lpfc_vport));
if (!shost) if (!shost)
goto out; goto out;
...@@ -1540,9 +1545,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) ...@@ -1540,9 +1545,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
vport->load_flag |= FC_LOADING; vport->load_flag |= FC_LOADING;
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
lpfc_get_vport_cfgparam(vport);
shost->unique_id = instance; shost->unique_id = instance;
shost->max_id = LPFC_MAX_TARGET; shost->max_id = LPFC_MAX_TARGET;
shost->max_lun = phba->cfg_max_luns; shost->max_lun = vport->cfg_max_luns;
shost->this_id = -1; shost->this_id = -1;
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
/* /*
...@@ -1551,7 +1557,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) ...@@ -1551,7 +1557,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
* max xri value determined in hba setup. * max xri value determined in hba setup.
*/ */
shost->can_queue = phba->cfg_hba_queue_depth - 10; shost->can_queue = phba->cfg_hba_queue_depth - 10;
if (fc_vport != NULL) { if (dev != &phba->pcidev->dev) {
shost->transportt = lpfc_vport_transport_template; shost->transportt = lpfc_vport_transport_template;
vport->port_type = LPFC_NPIV_PORT; vport->port_type = LPFC_NPIV_PORT;
} else { } else {
...@@ -1575,11 +1581,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) ...@@ -1575,11 +1581,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.function = lpfc_els_timeout;
vport->els_tmofunc.data = (unsigned long)vport; vport->els_tmofunc.data = (unsigned long)vport;
if (fc_vport != NULL) { error = scsi_add_host(shost, dev);
error = scsi_add_host(shost, &fc_vport->dev);
} else {
error = scsi_add_host(shost, &phba->pcidev->dev);
}
if (error) if (error)
goto out_put_shost; goto out_put_shost;
...@@ -1895,7 +1897,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1895,7 +1897,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
/* Initialize list of fabric iocbs */ /* Initialize list of fabric iocbs */
INIT_LIST_HEAD(&phba->fabric_iocb_list); INIT_LIST_HEAD(&phba->fabric_iocb_list);
vport = lpfc_create_port(phba, phba->brd_no, NULL); vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
if (!vport) if (!vport)
goto out_kthread_stop; goto out_kthread_stop;
......
...@@ -304,7 +304,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -304,7 +304,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
ndlp->nlp_rpi); ndlp->nlp_rpi);
if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)
ndlp->nlp_fcp_info |= CLASS2; ndlp->nlp_fcp_info |= CLASS2;
else else
ndlp->nlp_fcp_info |= CLASS3; ndlp->nlp_fcp_info |= CLASS3;
...@@ -392,7 +392,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -392,7 +392,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
} }
if ((vport->port_type == LPFC_NPIV_PORT && if ((vport->port_type == LPFC_NPIV_PORT &&
phba->cfg_vport_restrict_login)) { vport->cfg_restrict_login)) {
/* In order to preserve RPIs, we want to cleanup /* In order to preserve RPIs, we want to cleanup
* the default RPI the firmware created to rcv * the default RPI the firmware created to rcv
...@@ -564,10 +564,9 @@ static uint32_t ...@@ -564,10 +564,9 @@ static uint32_t
lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
/* Check config parameter use-adisc or FCP-2 */ /* Check config parameter use-adisc or FCP-2 */
if ((phba->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_ADISC; ndlp->nlp_flag |= NLP_NPR_ADISC;
...@@ -787,7 +786,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, ...@@ -787,7 +786,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_DID, ndlp->nlp_state,
ndlp->nlp_flag, ndlp->nlp_rpi); ndlp->nlp_flag, ndlp->nlp_rpi);
if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid)) if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
ndlp->nlp_fcp_info |= CLASS2; ndlp->nlp_fcp_info |= CLASS2;
else else
ndlp->nlp_fcp_info |= CLASS3; ndlp->nlp_fcp_info |= CLASS3;
...@@ -1358,7 +1357,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -1358,7 +1357,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
if (irsp->ulpStatus) { if (irsp->ulpStatus) {
if ((vport->port_type == LPFC_NPIV_PORT) && if ((vport->port_type == LPFC_NPIV_PORT) &&
phba->cfg_vport_restrict_login) { vport->cfg_restrict_login) {
goto out; goto out;
} }
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
...@@ -1380,7 +1379,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -1380,7 +1379,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
} }
if (!(ndlp->nlp_type & NLP_FCP_TARGET) && if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
(vport->port_type == LPFC_NPIV_PORT) && (vport->port_type == LPFC_NPIV_PORT) &&
phba->cfg_vport_restrict_login) { vport->cfg_restrict_login) {
out: out:
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_TARGET_REMOVE; ndlp->nlp_flag |= NLP_TARGET_REMOVE;
......
...@@ -84,22 +84,21 @@ lpfc_adjust_queue_depth(struct lpfc_hba *phba) ...@@ -84,22 +84,21 @@ lpfc_adjust_queue_depth(struct lpfc_hba *phba)
* SCSI command completion. * SCSI command completion.
*/ */
static inline void static inline void
lpfc_rampup_queue_depth(struct lpfc_hba *phba, lpfc_rampup_queue_depth(struct lpfc_vport *vport,
struct scsi_device *sdev) struct scsi_device *sdev)
{ {
unsigned long flags; unsigned long flags;
struct lpfc_hba *phba = vport->phba;
atomic_inc(&phba->num_cmd_success); atomic_inc(&phba->num_cmd_success);
if (phba->cfg_lun_queue_depth <= sdev->queue_depth) if (vport->cfg_lun_queue_depth <= sdev->queue_depth)
return; return;
spin_lock_irqsave(&phba->hbalock, flags); spin_lock_irqsave(&phba->hbalock, flags);
if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) || if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) ||
((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) { ((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) {
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return; return;
} }
phba->last_ramp_up_time = jiffies; phba->last_ramp_up_time = jiffies;
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
...@@ -627,16 +626,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, ...@@ -627,16 +626,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
if (!result) if (!result)
lpfc_rampup_queue_depth(phba, sdev); lpfc_rampup_queue_depth(vport, sdev);
if (!result && pnode != NULL && if (!result && pnode != NULL &&
((jiffies - pnode->last_ramp_up_time) > ((jiffies - pnode->last_ramp_up_time) >
LPFC_Q_RAMP_UP_INTERVAL * HZ) && LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
((jiffies - pnode->last_q_full_time) > ((jiffies - pnode->last_q_full_time) >
LPFC_Q_RAMP_UP_INTERVAL * HZ) && LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
(phba->cfg_lun_queue_depth > sdev->queue_depth)) { (vport->cfg_lun_queue_depth > sdev->queue_depth)) {
shost_for_each_device(tmp_sdev, sdev->host) { shost_for_each_device(tmp_sdev, sdev->host) {
if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) { if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){
if (tmp_sdev->id != sdev->id) if (tmp_sdev->id != sdev->id)
continue; continue;
if (tmp_sdev->ordered_tags) if (tmp_sdev->ordered_tags)
...@@ -1099,7 +1098,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -1099,7 +1098,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ);
if (++loop_count if (++loop_count
> (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT) > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT)
break; break;
} }
...@@ -1154,7 +1153,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) ...@@ -1154,7 +1153,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
loopcnt++; loopcnt++;
rdata = cmnd->device->hostdata; rdata = cmnd->device->hostdata;
if (!rdata || if (!rdata ||
(loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) { (loopcnt > ((vport->cfg_devloss_tmo * 2) + 1))){
lpfc_printf_log(phba, KERN_ERR, LOG_FCP, lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
"%d (%d):0721 LUN Reset rport " "%d (%d):0721 LUN Reset rport "
"failure: cnt x%x rdata x%p\n", "failure: cnt x%x rdata x%p\n",
...@@ -1230,7 +1229,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) ...@@ -1230,7 +1229,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
if (++loopcnt if (++loopcnt
> (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT)
break; break;
cnt = lpfc_sli_sum_iocb(phba, cnt = lpfc_sli_sum_iocb(phba,
...@@ -1339,7 +1338,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) ...@@ -1339,7 +1338,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
if (++loopcnt if (++loopcnt
> (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT) > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT)
break; break;
cnt = lpfc_sli_sum_iocb(phba, cnt = lpfc_sli_sum_iocb(phba,
...@@ -1386,7 +1385,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) ...@@ -1386,7 +1385,7 @@ lpfc_slave_alloc(struct scsi_device *sdev)
* extra. This list of scsi bufs exists for the lifetime of the driver. * extra. This list of scsi bufs exists for the lifetime of the driver.
*/ */
total = phba->total_scsi_bufs; total = phba->total_scsi_bufs;
num_to_alloc = phba->cfg_lun_queue_depth + 2; num_to_alloc = vport->cfg_lun_queue_depth + 2;
/* Allow some exchanges to be available always to complete discovery */ /* Allow some exchanges to be available always to complete discovery */
if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) { if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) {
...@@ -1435,9 +1434,9 @@ lpfc_slave_configure(struct scsi_device *sdev) ...@@ -1435,9 +1434,9 @@ lpfc_slave_configure(struct scsi_device *sdev)
struct fc_rport *rport = starget_to_rport(sdev->sdev_target); struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
if (sdev->tagged_supported) if (sdev->tagged_supported)
scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth); scsi_activate_tcq(sdev, vport->cfg_lun_queue_depth);
else else
scsi_deactivate_tcq(sdev, phba->cfg_lun_queue_depth); scsi_deactivate_tcq(sdev, vport->cfg_lun_queue_depth);
/* /*
* Initialize the fc transport attributes for the target * Initialize the fc transport attributes for the target
...@@ -1445,7 +1444,7 @@ lpfc_slave_configure(struct scsi_device *sdev) ...@@ -1445,7 +1444,7 @@ lpfc_slave_configure(struct scsi_device *sdev)
* target pointer is stored in the starget_data for the * target pointer is stored in the starget_data for the
* driver's sysfs entry point functions. * driver's sysfs entry point functions.
*/ */
rport->dev_loss_tmo = phba->cfg_devloss_tmo; rport->dev_loss_tmo = vport->cfg_devloss_tmo;
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
lpfc_sli_poll_fcp_ring(phba); lpfc_sli_poll_fcp_ring(phba);
...@@ -1483,3 +1482,23 @@ struct scsi_host_template lpfc_template = { ...@@ -1483,3 +1482,23 @@ struct scsi_host_template lpfc_template = {
.shost_attrs = lpfc_hba_attrs, .shost_attrs = lpfc_hba_attrs,
.max_sectors = 0xFFFF, .max_sectors = 0xFFFF,
}; };
struct scsi_host_template lpfc_vport_template = {
.module = THIS_MODULE,
.name = LPFC_DRIVER_NAME,
.info = lpfc_info,
.queuecommand = lpfc_queuecommand,
.eh_abort_handler = lpfc_abort_handler,
.eh_device_reset_handler= lpfc_device_reset_handler,
.eh_bus_reset_handler = lpfc_bus_reset_handler,
.slave_alloc = lpfc_slave_alloc,
.slave_configure = lpfc_slave_configure,
.slave_destroy = lpfc_slave_destroy,
.scan_finished = lpfc_scan_finished,
.this_id = -1,
.sg_tablesize = LPFC_SG_SEG_CNT,
.cmd_per_lun = LPFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = lpfc_vport_attrs,
.max_sectors = 0xFFFF,
};
...@@ -198,8 +198,8 @@ int ...@@ -198,8 +198,8 @@ int
lpfc_vport_create(struct fc_vport *fc_vport, bool disable) lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
{ {
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct lpfc_vport *pport = struct Scsi_Host *shost = fc_vport->shost;
(struct lpfc_vport *) fc_vport->shost->hostdata; struct lpfc_vport *pport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = pport->phba; struct lpfc_hba *phba = pport->phba;
struct lpfc_vport *vport = NULL; struct lpfc_vport *vport = NULL;
int instance; int instance;
...@@ -237,7 +237,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -237,7 +237,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
goto error_out; goto error_out;
} }
vport = lpfc_create_port(phba, instance, fc_vport); vport = lpfc_create_port(phba, instance, &fc_vport->dev);
if (!vport) { if (!vport) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
"%d:1811 Create VPORT failed: vpi x%x\n", "%d:1811 Create VPORT failed: vpi x%x\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment