Commit 41b194b8 authored by James Smart's avatar James Smart Committed by Christoph Hellwig
Browse files

lpfc: add sysfs interface to post NVME RSCN



To support scenarios which aren't bound to nvmetcli add port scenarios,
which is currently where the nvmet_fc transport invokes the discovery
event callbacks, a syfs attribute is added to lpfc which can be written
to cause an RSCN to be generated for the nport.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarArun Easi <aeasi@marvell.com>
Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 6f2589f4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -820,6 +820,7 @@ struct lpfc_hba {
	uint32_t cfg_use_msi;
	uint32_t cfg_auto_imax;
	uint32_t cfg_fcp_imax;
	uint32_t cfg_force_rscn;
	uint32_t cfg_cq_poll_threshold;
	uint32_t cfg_cq_max_proc_limit;
	uint32_t cfg_fcp_cpu_map;
+60 −0
Original line number Diff line number Diff line
@@ -4958,6 +4958,64 @@ static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
		   lpfc_request_firmware_upgrade_show,
		   lpfc_request_firmware_upgrade_store);

/**
 * lpfc_force_rscn_store
 *
 * @dev: class device that is converted into a Scsi_host.
 * @attr: device attribute, not used.
 * @buf: unused string
 * @count: unused variable.
 *
 * Description:
 * Force the switch to send a RSCN to all other NPorts in our zone
 * If we are direct connect pt2pt, build the RSCN command ourself
 * and send to the other NPort. Not supported for private loop.
 *
 * Returns:
 * 0      - on success
 * -EIO   - if command is not sent
 **/
static ssize_t
lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
		      const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
	int i;

	i = lpfc_issue_els_rscn(vport, 0);
	if (i)
		return -EIO;
	return strlen(buf);
}

/*
 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
 * connected to  the HBA.
 *
 * Value range is any ascii value
 */
static int lpfc_force_rscn;
module_param(lpfc_force_rscn, int, 0644);
MODULE_PARM_DESC(lpfc_force_rscn,
		 "Force an RSCN to be sent to all remote NPorts");
lpfc_param_show(force_rscn)

/**
 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
 * @phba: lpfc_hba pointer.
 * @val: unused value.
 *
 * Returns:
 * zero if val saved.
 **/
static int
lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
{
	return 0;
}
static DEVICE_ATTR_RW(lpfc_force_rscn);

/**
 * lpfc_fcp_imax_store
 *
@@ -5958,6 +6016,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_lpfc_nvme_oas,
	&dev_attr_lpfc_nvme_embed_cmd,
	&dev_attr_lpfc_fcp_imax,
	&dev_attr_lpfc_force_rscn,
	&dev_attr_lpfc_cq_poll_threshold,
	&dev_attr_lpfc_cq_max_proc_limit,
	&dev_attr_lpfc_fcp_cpu_map,
@@ -7005,6 +7064,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
	lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
	lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
	lpfc_force_rscn_init(phba, lpfc_force_rscn);
	lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
	lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
	lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);