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

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

[SCSI] lpfc 8.3.2 : Persistent Vport Support



Add support for persistent vport definitions at creation at boot time

Also includes a few misc fixes for:
- conversion to vpi name from vport slang name
- couple of small mailbox references
- some additional discovery mods

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent f4b4c68f
Loading
Loading
Loading
Loading
+31 −0
Original line number Original line Diff line number Diff line
@@ -2277,6 +2277,36 @@ lpfc_param_init(topology, 0, 0, 6)
static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
		lpfc_topology_show, lpfc_topology_store);
		lpfc_topology_show, lpfc_topology_store);


/**
 * lpfc_static_vport_show: Read callback function for
 *   lpfc_static_vport sysfs file.
 * @dev: Pointer to class device object.
 * @attr: device attribute structure.
 * @buf: Data buffer.
 *
 * This function is the read call back function for
 * lpfc_static_vport sysfs file. The lpfc_static_vport
 * sysfs file report the mageability of the vport.
 **/
static ssize_t
lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct Scsi_Host  *shost = class_to_shost(dev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	if (vport->vport_flag & STATIC_VPORT)
		sprintf(buf, "1\n");
	else
		sprintf(buf, "0\n");

	return strlen(buf);
}

/*
 * Sysfs attribute to control the statistical data collection.
 */
static DEVICE_ATTR(lpfc_static_vport, S_IRUGO,
		   lpfc_static_vport_show, NULL);


/**
/**
 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
@@ -3051,6 +3081,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
	&dev_attr_lpfc_enable_da_id,
	&dev_attr_lpfc_enable_da_id,
	&dev_attr_lpfc_max_scsicmpl_time,
	&dev_attr_lpfc_max_scsicmpl_time,
	&dev_attr_lpfc_stat_data_ctrl,
	&dev_attr_lpfc_stat_data_ctrl,
	&dev_attr_lpfc_static_vport,
	NULL,
	NULL,
};
};


+141 −39
Original line number Original line Diff line number Diff line
@@ -2079,6 +2079,128 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	return;
	return;
}
}


/**
 * lpfc_create_static_vport - Read HBA config region to create static vports.
 * @phba: pointer to lpfc hba data structure.
 *
 * This routine issue a DUMP mailbox command for config region 22 to get
 * the list of static vports to be created. The function create vports
 * based on the information returned from the HBA.
 **/
void
lpfc_create_static_vport(struct lpfc_hba *phba)
{
	LPFC_MBOXQ_t *pmb = NULL;
	MAILBOX_t *mb;
	struct static_vport_info *vport_info;
	int rc, i;
	struct fc_vport_identifiers vport_id;
	struct fc_vport *new_fc_vport;
	struct Scsi_Host *shost;
	struct lpfc_vport *vport;
	uint16_t offset = 0;
	uint8_t *vport_buff;

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"0542 lpfc_create_static_vport failed to"
				" allocate mailbox memory\n");
		return;
	}

	mb = &pmb->u.mb;

	vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL);
	if (!vport_info) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"0543 lpfc_create_static_vport failed to"
				" allocate vport_info\n");
		mempool_free(pmb, phba->mbox_mem_pool);
		return;
	}

	vport_buff = (uint8_t *) vport_info;
	do {
		lpfc_dump_static_vport(phba, pmb, offset);
		pmb->vport = phba->pport;
		rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO);

		if ((rc != MBX_SUCCESS) || mb->mbxStatus) {
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0544 lpfc_create_static_vport failed to"
				" issue dump mailbox command ret 0x%x "
				"status 0x%x\n",
				rc, mb->mbxStatus);
			goto out;
		}

		if (mb->un.varDmp.word_cnt >
			sizeof(struct static_vport_info) - offset)
			mb->un.varDmp.word_cnt =
			sizeof(struct static_vport_info) - offset;

		lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
			vport_buff + offset,
			mb->un.varDmp.word_cnt);
		offset += mb->un.varDmp.word_cnt;

	} while (mb->un.varDmp.word_cnt &&
		offset < sizeof(struct static_vport_info));


	if ((le32_to_cpu(vport_info->signature) != VPORT_INFO_SIG) ||
		((le32_to_cpu(vport_info->rev) & VPORT_INFO_REV_MASK)
			!= VPORT_INFO_REV)) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			"0545 lpfc_create_static_vport bad"
			" information header 0x%x 0x%x\n",
			le32_to_cpu(vport_info->signature),
			le32_to_cpu(vport_info->rev) & VPORT_INFO_REV_MASK);

		goto out;
	}

	shost = lpfc_shost_from_vport(phba->pport);

	for (i = 0; i < MAX_STATIC_VPORT_COUNT; i++) {
		memset(&vport_id, 0, sizeof(vport_id));
		vport_id.port_name = wwn_to_u64(vport_info->vport_list[i].wwpn);
		vport_id.node_name = wwn_to_u64(vport_info->vport_list[i].wwnn);
		if (!vport_id.port_name || !vport_id.node_name)
			continue;

		vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR;
		vport_id.vport_type = FC_PORTTYPE_NPIV;
		vport_id.disable = false;
		new_fc_vport = fc_vport_create(shost, 0, &vport_id);

		if (!new_fc_vport) {
			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
				"0546 lpfc_create_static_vport failed to"
				" create vport \n");
			continue;
		}

		vport = *(struct lpfc_vport **)new_fc_vport->dd_data;
		vport->vport_flag |= STATIC_VPORT;
	}

out:
	/*
	 * If this is timed out command, setting NULL to context2 tell SLI
	 * layer not to use this buffer.
	 */
	spin_lock_irq(&phba->hbalock);
	pmb->context2 = NULL;
	spin_unlock_irq(&phba->hbalock);
	kfree(vport_info);
	if (rc != MBX_TIMEOUT)
		mempool_free(pmb, phba->mbox_mem_pool);

	return;
}

/*
/*
 * This routine handles processing a Fabric REG_LOGIN mailbox
 * This routine handles processing a Fabric REG_LOGIN mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * command upon completion. It is setup in the LPFC_MBOXQ
@@ -2089,16 +2211,17 @@ void
lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;
	MAILBOX_t *mb = &pmb->mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_nodelist *ndlp;
	struct lpfc_nodelist *ndlp;
	struct lpfc_vport **vports;
	int i;


	ndlp = (struct lpfc_nodelist *) pmb->context2;
	ndlp = (struct lpfc_nodelist *) pmb->context2;
	pmb->context1 = NULL;
	pmb->context1 = NULL;
	pmb->context2 = NULL;
	pmb->context2 = NULL;
	if (mb->mbxStatus) {
	if (mb->mbxStatus) {
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
				 "0258 Register Fabric login error: 0x%x\n",
				 mb->mbxStatus);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
		kfree(mp);
		mempool_free(pmb, phba->mbox_mem_pool);
		mempool_free(pmb, phba->mbox_mem_pool);
@@ -2117,9 +2240,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		}
		}


		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
				 "0258 Register Fabric login error: 0x%x\n",
				 mb->mbxStatus);
		/* Decrement the reference count to ndlp after the reference
		/* Decrement the reference count to ndlp after the reference
		 * to the ndlp are done.
		 * to the ndlp are done.
		 */
		 */
@@ -2128,34 +2248,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	}
	}


	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_flag |= NLP_RPI_VALID;
	ndlp->nlp_type |= NLP_FABRIC;
	ndlp->nlp_type |= NLP_FABRIC;
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);


	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
		vports = lpfc_create_vport_work_array(phba);
		lpfc_start_fdiscs(phba);
		if (vports != NULL)
			for(i = 0;
			    i <= phba->max_vpi && vports[i] != NULL;
			    i++) {
				if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
					continue;
				if (phba->fc_topology == TOPOLOGY_LOOP) {
					lpfc_vport_set_state(vports[i],
							FC_VPORT_LINKDOWN);
					continue;
				}
				if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
					lpfc_initial_fdisc(vports[i]);
				else {
					lpfc_vport_set_state(vports[i],
						FC_VPORT_NO_FABRIC_SUPP);
					lpfc_printf_vlog(vport, KERN_ERR,
							 LOG_ELS,
							"0259 No NPIV "
							"Fabric support\n");
				}
			}
		lpfc_destroy_vport_work_array(phba, vports);
		lpfc_do_scr_ns_plogi(phba, vport);
		lpfc_do_scr_ns_plogi(phba, vport);
	}
	}


@@ -2179,13 +2277,16 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
void
void
lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
{
	MAILBOX_t *mb = &pmb->mb;
	MAILBOX_t *mb = &pmb->u.mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
	struct lpfc_vport *vport = pmb->vport;
	struct lpfc_vport *vport = pmb->vport;


	if (mb->mbxStatus) {
	if (mb->mbxStatus) {
out:
out:
		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
				 "0260 Register NameServer error: 0x%x\n",
				 mb->mbxStatus);
		/* decrement the node reference count held for this
		/* decrement the node reference count held for this
		 * callback function.
		 * callback function.
		 */
		 */
@@ -2209,15 +2310,13 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
			return;
			return;
		}
		}
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
				 "0260 Register NameServer error: 0x%x\n",
				 mb->mbxStatus);
		return;
		return;
	}
	}


	pmb->context1 = NULL;
	pmb->context1 = NULL;


	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_flag |= NLP_RPI_VALID;
	ndlp->nlp_type |= NLP_FABRIC;
	ndlp->nlp_type |= NLP_FABRIC;
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);


@@ -2718,7 +2817,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba,
	if (pring->ringno == LPFC_ELS_RING) {
	if (pring->ringno == LPFC_ELS_RING) {
		switch (icmd->ulpCommand) {
		switch (icmd->ulpCommand) {
		case CMD_GEN_REQUEST64_CR:
		case CMD_GEN_REQUEST64_CR:
			if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi)
			if (iocb->context_un.ndlp == ndlp)
				return 1;
				return 1;
		case CMD_ELS_REQUEST64_CR:
		case CMD_ELS_REQUEST64_CR:
			if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID)
			if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID)
@@ -2765,7 +2864,7 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
	 */
	 */
	psli = &phba->sli;
	psli = &phba->sli;
	rpi = ndlp->nlp_rpi;
	rpi = ndlp->nlp_rpi;
	if (rpi) {
	if (ndlp->nlp_flag & NLP_RPI_VALID) {
		/* Now process each ring */
		/* Now process each ring */
		for (i = 0; i < psli->num_rings; i++) {
		for (i = 0; i < psli->num_rings; i++) {
			pring = &psli->ring[i];
			pring = &psli->ring[i];
@@ -2813,7 +2912,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	LPFC_MBOXQ_t    *mbox;
	LPFC_MBOXQ_t    *mbox;
	int rc;
	int rc;


	if (ndlp->nlp_rpi) {
	if (ndlp->nlp_flag & NLP_RPI_VALID) {
		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
		if (mbox) {
		if (mbox) {
			lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
			lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
@@ -2825,6 +2924,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
		}
		}
		lpfc_no_rpi(phba, ndlp);
		lpfc_no_rpi(phba, ndlp);
		ndlp->nlp_rpi = 0;
		ndlp->nlp_rpi = 0;
		ndlp->nlp_flag &= ~NLP_RPI_VALID;
		return 1;
		return 1;
	}
	}
	return 0;
	return 0;
@@ -2972,13 +3072,14 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
	int rc;
	int rc;


	lpfc_cancel_retry_delay_tmo(vport, ndlp);
	lpfc_cancel_retry_delay_tmo(vport, ndlp);
	if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) {
	if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
	    !(ndlp->nlp_flag & NLP_RPI_VALID)) {
		/* For this case we need to cleanup the default rpi
		/* For this case we need to cleanup the default rpi
		 * allocated by the firmware.
		 * allocated by the firmware.
		 */
		 */
		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
			!= NULL) {
			!= NULL) {
			rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID,
			rc = lpfc_reg_rpi(phba, vport->vpi, ndlp->nlp_DID,
			    (uint8_t *) &vport->fc_sparam, mbox, 0);
			    (uint8_t *) &vport->fc_sparam, mbox, 0);
			if (rc) {
			if (rc) {
				mempool_free(mbox, phba->mbox_mem_pool);
				mempool_free(mbox, phba->mbox_mem_pool);
@@ -3713,6 +3814,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	pmb->context1 = NULL;
	pmb->context1 = NULL;


	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_flag |= NLP_RPI_VALID;
	ndlp->nlp_type |= NLP_FABRIC;
	ndlp->nlp_type |= NLP_FABRIC;
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);


+1 −0
Original line number Original line Diff line number Diff line
@@ -385,6 +385,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
	/* Update the fc_host data structures with new wwn. */
	/* Update the fc_host data structures with new wwn. */
	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
	fc_host_max_npiv_vports(shost) = phba->max_vpi;


	/* If no serial number in VPD data, use low 6 bytes of WWNN */
	/* If no serial number in VPD data, use low 6 bytes of WWNN */
	/* This should be consolidated into parse_vpd ? - mr */
	/* This should be consolidated into parse_vpd ? - mr */
+38 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,44 @@
#include "lpfc_crtn.h"
#include "lpfc_crtn.h"
#include "lpfc_compat.h"
#include "lpfc_compat.h"


/**
 * lpfc_dump_static_vport - Dump HBA's static vport information.
 * @phba: pointer to lpfc hba data structure.
 * @pmb: pointer to the driver internal queue element for mailbox command.
 * @offset: offset for dumping vport info.
 *
 * The dump mailbox command provides a method for the device driver to obtain
 * various types of information from the HBA device.
 *
 * This routine prepares the mailbox command for dumping list of static
 * vports to be created.
 **/
void
lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
		uint16_t offset)
{
	MAILBOX_t *mb;
	void *ctx;

	mb = &pmb->u.mb;
	ctx = pmb->context2;

	/* Setup to dump vport info region */
	memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
	mb->mbxCommand = MBX_DUMP_MEMORY;
	mb->un.varDmp.cv = 1;
	mb->un.varDmp.type = DMP_NV_PARAMS;
	mb->un.varDmp.entry_index = offset;
	mb->un.varDmp.region_id = DMP_REGION_VPORT;
	mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t);
	mb->un.varDmp.co = 0;
	mb->un.varDmp.resp_offset = 0;
	pmb->context2 = ctx;
	mb->mbxOwner = OWN_HOST;

	return;
}

/**
/**
 * lpfc_dump_mem - Prepare a mailbox command for retrieving HBA's VPD memory
 * lpfc_dump_mem - Prepare a mailbox command for retrieving HBA's VPD memory
 * @phba: pointer to lpfc hba data structure.
 * @phba: pointer to lpfc hba data structure.
+3 −3
Original line number Original line Diff line number Diff line
@@ -329,7 +329,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)


	vports = lpfc_create_vport_work_array(phba);
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
	if (vports != NULL)
		for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			shost = lpfc_shost_from_vport(vports[i]);
			shost = lpfc_shost_from_vport(vports[i]);
			shost_for_each_device(sdev, shost) {
			shost_for_each_device(sdev, shost) {
				new_queue_depth =
				new_queue_depth =
@@ -383,7 +383,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)


	vports = lpfc_create_vport_work_array(phba);
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
	if (vports != NULL)
		for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			shost = lpfc_shost_from_vport(vports[i]);
			shost = lpfc_shost_from_vport(vports[i]);
			shost_for_each_device(sdev, shost) {
			shost_for_each_device(sdev, shost) {
				if (vports[i]->cfg_lun_queue_depth <=
				if (vports[i]->cfg_lun_queue_depth <=
@@ -431,7 +431,7 @@ lpfc_scsi_dev_block(struct lpfc_hba *phba)


	vports = lpfc_create_vport_work_array(phba);
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
	if (vports != NULL)
		for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
			shost = lpfc_shost_from_vport(vports[i]);
			shost = lpfc_shost_from_vport(vports[i]);
			shost_for_each_device(sdev, shost) {
			shost_for_each_device(sdev, shost) {
				rport = starget_to_rport(scsi_target(sdev));
				rport = starget_to_rport(scsi_target(sdev));
Loading