summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2017-12-04 14:45:05 -0800
committerMartin K. Petersen <martin.petersen@oracle.com>2017-12-07 21:07:04 -0500
commit5ef696aa9f3ccf999552d924c4e21a348f2bbea9 (patch)
treedbde1ac295ca9e47c1f83d2d91b9e4a26864bdf7 /drivers/scsi/qla2xxx/qla_os.c
parent3be63b1e1838e35ce93e83f19573e949f4b389b4 (diff)
downloadop-kernel-dev-5ef696aa9f3ccf999552d924c4e21a348f2bbea9.zip
op-kernel-dev-5ef696aa9f3ccf999552d924c4e21a348f2bbea9.tar.gz
scsi: qla2xxx: Relogin to target port on a cable swap
If user swaps one target port for another target port for same switch port, the new target port is not being recognized by the driver. Current code assumes that old Target port has recovered from link down. The fix will ask switch what is the WWPN of a specific NportID (GPNID) rather than assuming it's the same Target port which has came back. Fixes: 726b85487067d ("qla2xxx: Add framework for async fabric discovery") Cc: <stable@vger.kernel.org> # 4.10+ Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e71d99b..820d1c1 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4760,10 +4760,39 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
if (fcport) {
- if (pla)
+ if (pla) {
qlt_plogi_ack_unref(vha, pla);
- else
- qla24xx_async_gffid(vha, fcport);
+ } else {
+ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+ tfcp = qla2x00_find_fcport_by_nportid(vha,
+ &e->u.new_sess.id, 1);
+ if (tfcp && (tfcp != fcport)) {
+ /*
+ * We have a conflict fcport with same NportID.
+ */
+ ql_dbg(ql_dbg_disc, vha, 0xffff,
+ "%s %8phC found conflict b4 add. DS %d LS %d\n",
+ __func__, tfcp->port_name, tfcp->disc_state,
+ tfcp->fw_login_state);
+
+ switch (tfcp->disc_state) {
+ case DSC_DELETED:
+ break;
+ case DSC_DELETE_PEND:
+ fcport->login_pause = 1;
+ tfcp->conflict = fcport;
+ break;
+ default:
+ fcport->login_pause = 1;
+ tfcp->conflict = fcport;
+ qlt_schedule_sess_for_deletion_lock
+ (tfcp);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+ qla24xx_async_gnl(vha, fcport);
+ }
}
if (free_fcport) {
OpenPOWER on IntegriCloud