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

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

[SCSI] lpfc 8.1.11 : Add soft_wwnn sysfs attribute, rename soft_wwn_enable



The driver now allows both wwpn and wwnn to be set.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 18a3b596
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -306,6 +306,7 @@ struct lpfc_hba {
	uint32_t cfg_use_msi;
	uint32_t cfg_use_msi;
	uint32_t cfg_sg_seg_cnt;
	uint32_t cfg_sg_seg_cnt;
	uint32_t cfg_sg_dma_buf_size;
	uint32_t cfg_sg_dma_buf_size;
	uint64_t cfg_soft_wwnn;
	uint64_t cfg_soft_wwpn;
	uint64_t cfg_soft_wwpn;


	uint32_t dev_loss_tmo_changed;
	uint32_t dev_loss_tmo_changed;
@@ -358,7 +359,7 @@ struct lpfc_hba {
#define VPD_PORT            0x8         /* valid vpd port data */
#define VPD_PORT            0x8         /* valid vpd port data */
#define VPD_MASK            0xf         /* mask for any vpd data */
#define VPD_MASK            0xf         /* mask for any vpd data */


	uint8_t soft_wwpn_enable;
	uint8_t soft_wwn_enable;


	struct timer_list fcp_poll_timer;
	struct timer_list fcp_poll_timer;
	struct timer_list els_tmofunc;
	struct timer_list els_tmofunc;
+74 −10
Original line number Original line Diff line number Diff line
@@ -552,10 +552,10 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);




static char *lpfc_soft_wwpn_key = "C99G71SL8032A";
static char *lpfc_soft_wwn_key = "C99G71SL8032A";


static ssize_t
static ssize_t
lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf,
lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf,
				size_t count)
				size_t count)
{
{
	struct Scsi_Host *host = class_to_shost(cdev);
	struct Scsi_Host *host = class_to_shost(cdev);
@@ -579,15 +579,15 @@ lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf,
	if (buf[cnt-1] == '\n')
	if (buf[cnt-1] == '\n')
		cnt--;
		cnt--;


	if ((cnt != strlen(lpfc_soft_wwpn_key)) ||
	if ((cnt != strlen(lpfc_soft_wwn_key)) ||
	    (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0))
	    (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
		return -EINVAL;
		return -EINVAL;


	phba->soft_wwpn_enable = 1;
	phba->soft_wwn_enable = 1;
	return count;
	return count;
}
}
static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL,
static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL,
				lpfc_soft_wwpn_enable_store);
				lpfc_soft_wwn_enable_store);


static ssize_t
static ssize_t
lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
@@ -613,12 +613,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
	if (buf[cnt-1] == '\n')
	if (buf[cnt-1] == '\n')
		cnt--;
		cnt--;


	if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) ||
	if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) ||
	    ((cnt == 17) && (*buf++ != 'x')) ||
	    ((cnt == 17) && (*buf++ != 'x')) ||
	    ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
	    ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
		return -EINVAL;
		return -EINVAL;


	phba->soft_wwpn_enable = 0;
	phba->soft_wwn_enable = 0;


	memset(wwpn, 0, sizeof(wwpn));
	memset(wwpn, 0, sizeof(wwpn));


@@ -639,6 +639,8 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
	}
	}
	phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
	phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
	fc_host_port_name(host) = phba->cfg_soft_wwpn;
	fc_host_port_name(host) = phba->cfg_soft_wwpn;
	if (phba->cfg_soft_wwnn)
		fc_host_node_name(host) = phba->cfg_soft_wwnn;


	dev_printk(KERN_NOTICE, &phba->pcidev->dev,
	dev_printk(KERN_NOTICE, &phba->pcidev->dev,
		   "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
		   "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
@@ -664,6 +666,66 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
			 lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);
			 lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);


static ssize_t
lpfc_soft_wwnn_show(struct class_device *cdev, char *buf)
{
	struct Scsi_Host *host = class_to_shost(cdev);
	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
	return snprintf(buf, PAGE_SIZE, "0x%llx\n",
			(unsigned long long)phba->cfg_soft_wwnn);
}


static ssize_t
lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count)
{
	struct Scsi_Host *host = class_to_shost(cdev);
	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
	unsigned int i, j, cnt=count;
	u8 wwnn[8];

	/* count may include a LF at end of string */
	if (buf[cnt-1] == '\n')
		cnt--;

	if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) ||
	    ((cnt == 17) && (*buf++ != 'x')) ||
	    ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
		return -EINVAL;

	/*
	 * Allow wwnn to be set many times, as long as the enable is set.
	 * However, once the wwpn is set, everything locks.
	 */

	memset(wwnn, 0, sizeof(wwnn));

	/* Validate and store the new name */
	for (i=0, j=0; i < 16; i++) {
		if ((*buf >= 'a') && (*buf <= 'f'))
			j = ((j << 4) | ((*buf++ -'a') + 10));
		else if ((*buf >= 'A') && (*buf <= 'F'))
			j = ((j << 4) | ((*buf++ -'A') + 10));
		else if ((*buf >= '0') && (*buf <= '9'))
			j = ((j << 4) | (*buf++ -'0'));
		else
			return -EINVAL;
		if (i % 2) {
			wwnn[i/2] = j & 0xff;
			j = 0;
		}
	}
	phba->cfg_soft_wwnn = wwn_to_u64(wwnn);

	dev_printk(KERN_NOTICE, &phba->pcidev->dev,
		   "lpfc%d: soft_wwnn set. Value will take effect upon "
		   "setting of the soft_wwpn\n", phba->brd_no);

	return count;
}
static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\
			 lpfc_soft_wwnn_show, lpfc_soft_wwnn_store);



static int lpfc_poll = 0;
static int lpfc_poll = 0;
module_param(lpfc_poll, int, 0);
module_param(lpfc_poll, int, 0);
@@ -1009,8 +1071,9 @@ struct class_device_attribute *lpfc_host_attrs[] = {
	&class_device_attr_lpfc_poll,
	&class_device_attr_lpfc_poll,
	&class_device_attr_lpfc_poll_tmo,
	&class_device_attr_lpfc_poll_tmo,
	&class_device_attr_lpfc_use_msi,
	&class_device_attr_lpfc_use_msi,
	&class_device_attr_lpfc_soft_wwnn,
	&class_device_attr_lpfc_soft_wwpn,
	&class_device_attr_lpfc_soft_wwpn,
	&class_device_attr_lpfc_soft_wwpn_enable,
	&class_device_attr_lpfc_soft_wwn_enable,
	NULL,
	NULL,
};
};


@@ -1815,6 +1878,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
	lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
	lpfc_nodev_tmo_init(phba, lpfc_nodev_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_wwpn = 0L;
	phba->cfg_soft_wwpn = 0L;


	/*
	/*
+2 −0
Original line number Original line Diff line number Diff line
@@ -672,6 +672,8 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)


	memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,
	memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,
	       sizeof (struct serv_parm));
	       sizeof (struct serv_parm));
	if (phba->cfg_soft_wwnn)
		u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
	if (phba->cfg_soft_wwpn)
	if (phba->cfg_soft_wwpn)
		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
	memcpy((uint8_t *) & phba->fc_nodename,
	memcpy((uint8_t *) & phba->fc_nodename,
+2 −0
Original line number Original line Diff line number Diff line
@@ -268,6 +268,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
	kfree(mp);
	kfree(mp);
	pmb->context1 = NULL;
	pmb->context1 = NULL;


	if (phba->cfg_soft_wwnn)
		u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
	if (phba->cfg_soft_wwpn)
	if (phba->cfg_soft_wwpn)
		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
		u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
	memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName,
	memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName,