diff options
author | Quinn Tran <quinn.tran@cavium.com> | 2018-08-02 13:16:53 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-08-02 16:56:18 -0400 |
commit | f6602f3befbb9979cdb031e32211358dd008d05e (patch) | |
tree | 898bc878331b99585bae52af95890d92ee2a7aea /drivers/scsi | |
parent | b2000805a9759d315f56eecaca7779aa9197a72f (diff) | |
download | linux-f6602f3befbb9979cdb031e32211358dd008d05e.tar.bz2 |
scsi: qla2xxx: Fix Management Server NPort handle reservation logic
After selecting the NPort handle/loop_id, set a bit in the loop_id_map to
prevent others from selecting the same NPort handle.
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 28 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 3 |
4 files changed, 32 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f68eb6096559..00fbd49a9a7a 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -118,6 +118,7 @@ extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); +int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *); /* * Global Data in qla_os.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a10a8bb895e9..9d1a8b2c41a9 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5616,6 +5616,34 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) } +/* FW does not set aside Loop id for MGMT Server/FFFFFAh */ +int +qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *vha) +{ + int loop_id = FC_NO_LOOP_ID; + int lid = NPH_MGMT_SERVER - vha->vp_idx; + unsigned long flags; + struct qla_hw_data *ha = vha->hw; + + if (vha->vp_idx == 0) { + set_bit(NPH_MGMT_SERVER, ha->loop_id_map); + return NPH_MGMT_SERVER; + } + + /* pick id from high and work down to low */ + spin_lock_irqsave(&ha->vport_slock, flags); + for (; lid > 0; lid--) { + if (!test_bit(lid, vha->hw->loop_id_map)) { + set_bit(lid, vha->hw->loop_id_map); + loop_id = lid; + break; + } + } + spin_unlock_irqrestore(&ha->vport_slock, flags); + + return loop_id; +} + /* * qla2x00_fabric_login * Issue fabric login command. diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index f6f0a759a7c2..14bc88bc4a5a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -485,7 +485,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) "Couldn't allocate vp_id.\n"); goto create_vhost_failed; } - vha->mgmt_svr_loop_id = NPH_MGMT_SERVER; + vha->mgmt_svr_loop_id = qla2x00_reserve_mgmt_server_loop_id(vha); vha->dpc_flags = 0L; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 04e0c7f51e68..48d1003c8178 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3048,7 +3048,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host = base_vha->host; base_vha->req = req; if (IS_QLA2XXX_MIDTYPE(ha)) - base_vha->mgmt_svr_loop_id = NPH_MGMT_SERVER; + base_vha->mgmt_svr_loop_id = + qla2x00_reserve_mgmt_server_loop_id(base_vha); else base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER + base_vha->vp_idx; |