scsi: qla2xxx: Fix Management Server NPort handle reservation logic
authorQuinn Tran <quinn.tran@cavium.com>
Thu, 2 Aug 2018 20:16:53 +0000 (13:16 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 2 Aug 2018 20:56:18 +0000 (16:56 -0400)
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>
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c

index f68eb60..00fbd49 100644 (file)
@@ -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.
  */
index a10a8bb..9d1a8b2 100644 (file)
@@ -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.
index f6f0a75..14bc88b 100644 (file)
@@ -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;
 
index 04e0c7f..48d1003 100644 (file)
@@ -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;