]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/scsi/qla2xxx/qla_init.c
[SCSI] qla2xxx: Ensure the timer and DPC routines complete prior to midlayer tear...
[mirror_ubuntu-bionic-kernel.git] / drivers / scsi / qla2xxx / qla_init.c
index 986501759ad4910fa6b93c7db75d355001c47ad8..0febfa648c34807134a9bfcf717cd2b694c0c58c 100644 (file)
@@ -816,7 +816,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
                qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
                    FCE_SIZE / 1024);
 
-               fce_size = sizeof(struct qla2xxx_fce_chain) + EFT_SIZE;
+               fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
                ha->flags.fce_enabled = 1;
                ha->fce_dma = tc_dma;
                ha->fce = tc;
@@ -963,6 +963,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
        struct qla_hw_data *ha = vha->hw;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
        unsigned long flags;
+       uint16_t fw_major_version;
 
        if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
                /* Disable SRAM, Instruction RAM and GP RAM parity.  */
@@ -986,13 +987,15 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 
                        rval = qla2x00_execute_fw(vha, srisc_address);
                        /* Retrieve firmware information. */
-                       if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
+                       if (rval == QLA_SUCCESS) {
+                               fw_major_version = ha->fw_major_version;
                                qla2x00_get_fw_version(vha,
                                    &ha->fw_major_version,
                                    &ha->fw_minor_version,
                                    &ha->fw_subminor_version,
                                    &ha->fw_attributes, &ha->fw_memory_size,
-                                   ha->mpi_version, &ha->mpi_capabilities);
+                                   ha->mpi_version, &ha->mpi_capabilities,
+                                   ha->phy_version);
                                ha->flags.npiv_supported = 0;
                                if (IS_QLA2XXX_MIDTYPE(ha) &&
                                         (ha->fw_attributes & BIT_2)) {
@@ -1003,10 +1006,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
                                                ha->max_npiv_vports =
                                                    MIN_MULTI_ID_FABRIC - 1;
                                }
-                               qla2x00_resize_request_q(vha);
-
-                               if (ql2xallocfwdump)
-                                       qla2x00_alloc_fw_dump(vha);
+                               if (!fw_major_version) {
+                                       qla2x00_resize_request_q(vha);
+                                       if (ql2xallocfwdump)
+                                               qla2x00_alloc_fw_dump(vha);
+                               }
                        }
                } else {
                        DEBUG2(printk(KERN_INFO
@@ -1308,8 +1312,12 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 
        DEBUG(printk("scsi(%ld): Issue init firmware.\n", vha->host_no));
 
-       if (ha->flags.npiv_supported)
+       if (ha->flags.npiv_supported) {
+               if (ha->operating_mode == LOOP)
+                       ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
                mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
+       }
+
 
        mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
 
@@ -2610,6 +2618,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
        port_id_t       wrap, nxt_d_id;
        struct qla_hw_data *ha = vha->hw;
        struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
+       struct scsi_qla_host *tvp;
 
        rval = QLA_SUCCESS;
 
@@ -2709,7 +2718,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
                /* Bypass virtual ports of the same host. */
                found = 0;
                if (ha->num_vhosts) {
-                       list_for_each_entry(vp, &ha->vp_list, list) {
+                       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                                if (new_fcport->d_id.b24 == vp->d_id.b24) {
                                        found = 1;
                                        break;
@@ -2832,6 +2841,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
        uint16_t first_loop_id;
        struct qla_hw_data *ha = vha->hw;
        struct scsi_qla_host *vp;
+       struct scsi_qla_host *tvp;
 
        rval = QLA_SUCCESS;
 
@@ -2856,7 +2866,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
                /* Check for loop ID being already in use. */
                found = 0;
                fcport = NULL;
-               list_for_each_entry(vp, &ha->vp_list, list) {
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                        list_for_each_entry(fcport, &vp->vp_fcports, list) {
                                if (fcport->loop_id == dev->loop_id &&
                                                                fcport != dev) {
@@ -3291,6 +3301,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
        uint8_t        status = 0;
        struct qla_hw_data *ha = vha->hw;
        struct scsi_qla_host *vp;
+       struct scsi_qla_host *tvp;
        struct req_que *req = ha->req_q_map[0];
 
        if (vha->flags.online) {
@@ -3306,7 +3317,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
                if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
                        atomic_set(&vha->loop_state, LOOP_DOWN);
                        qla2x00_mark_all_devices_lost(vha, 0);
-                       list_for_each_entry(vp, &ha->vp_list, list)
+                       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
                               qla2x00_mark_all_devices_lost(vp, 0);
                } else {
                        if (!atomic_read(&vha->loop_down_timer))
@@ -3403,7 +3414,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
                DEBUG(printk(KERN_INFO
                                "qla2x00_abort_isp(%ld): succeeded.\n",
                                vha->host_no));
-               list_for_each_entry(vp, &ha->vp_list, list) {
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                        if (vp->vp_idx)
                                qla2x00_vp_abort_isp(vp);
                }
@@ -3428,7 +3439,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
 static int
 qla2x00_restart_isp(scsi_qla_host_t *vha)
 {
-       uint8_t         status = 0;
+       int status = 0;
        uint32_t wait_time;
        struct qla_hw_data *ha = vha->hw;
        struct req_que *req = ha->req_q_map[0];
@@ -4445,6 +4456,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
                icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
        }
 
+       /* Use extended-initialization control block. */
+       memcpy(ha->ex_init_cb, &nv->ex_version, sizeof(*ha->ex_init_cb));
+
        /*
         * Setup driver NVRAM options.
         */