return strlen(buf);
 }
 
+static ssize_t
+qla_zio_threshold_show(struct device *dev, struct device_attribute *attr,
+                      char *buf)
+{
+       scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+       return scnprintf(buf, PAGE_SIZE, "%d exchanges\n",
+           vha->hw->last_zio_threshold);
+}
+
+static ssize_t
+qla_zio_threshold_store(struct device *dev, struct device_attribute *attr,
+    const char *buf, size_t count)
+{
+       scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+       int val = 0;
+
+       if (vha->hw->zio_mode != QLA_ZIO_MODE_6)
+               return -EINVAL;
+       if (sscanf(buf, "%d", &val) != 1)
+               return -EINVAL;
+       if (val > 256)
+               return -ERANGE;
+
+       atomic_set(&vha->hw->zio_threshold, val);
+       return strlen(buf);
+}
+
 static ssize_t
 qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
                    char *buf)
 static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL);
 static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL);
 static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL);
+static DEVICE_ATTR(zio_threshold, 0644,
+    qla_zio_threshold_show,
+    qla_zio_threshold_store);
 
 struct device_attribute *qla2x00_host_attrs[] = {
        &dev_attr_driver_version,
        &dev_attr_pep_version,
        &dev_attr_min_link_speed,
        &dev_attr_max_speed_sup,
+       &dev_attr_zio_threshold,
        NULL,
 };
 
 
 
        atomic_t        nvme_active_aen_cnt;
        uint16_t        nvme_last_rptd_aen;             /* Last recorded aen count */
+
+       atomic_t zio_threshold;
+       uint16_t last_zio_threshold;
+#define DEFAULT_ZIO_THRESHOLD 64
 };
 
 #define FW_ABILITY_MAX_SPEED_MASK      0xFUL
 #define FX00_CRITEMP_RECOVERY  25
 #define FX00_HOST_INFO_RESEND  26
 #define QPAIR_ONLINE_CHECK_NEEDED      27
-#define SET_ZIO_THRESHOLD_NEEDED       28
+#define SET_NVME_ZIO_THRESHOLD_NEEDED  28
 #define DETECT_SFP_CHANGE      29
 #define N2N_LOGIN_NEEDED       30
 #define IOCB_WORK_ACTIVE       31
+#define SET_ZIO_THRESHOLD_NEEDED 32
 
        unsigned long   pci_flags;
 #define PFLG_DISCONNECTED      0       /* PCI device removed */
 
                        if (rval == QLA_SUCCESS) {
                                qla24xx_detect_sfp(vha);
 
+                               if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) &&
+                                   (ha->zio_mode == QLA_ZIO_MODE_6))
+                                       qla27xx_set_zio_threshold(vha,
+                                           ha->last_zio_threshold);
+
                                rval = qla2x00_set_exlogins_buffer(vha);
                                if (rval != QLA_SUCCESS)
                                        goto failed;
 
        { MBC_GET_ADAPTER_LOOP_ID },
        { MBC_READ_SFP },
        { MBC_GET_RNID_PARAMS },
+       { MBC_GET_SET_ZIO_THRESHOLD },
 };
 
 static int is_rom_cmd(uint16_t cmd)
 
        atomic_set(&ha->num_pend_mbx_stage1, 0);
        atomic_set(&ha->num_pend_mbx_stage2, 0);
        atomic_set(&ha->num_pend_mbx_stage3, 0);
+       atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
+       ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
 
        /* Assign ISP specific operations. */
        if (IS_QLA2100(ha)) {
                        mutex_unlock(&ha->mq_lock);
                }
 
-               if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, &base_vha->dpc_flags)) {
+               if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED,
+                   &base_vha->dpc_flags)) {
                        ql_log(ql_log_info, base_vha, 0xffffff,
                                "nvme: SET ZIO Activity exchange threshold to %d.\n",
                                                ha->nvme_last_rptd_aen);
-                       if (qla27xx_set_zio_threshold(base_vha, ha->nvme_last_rptd_aen)) {
+                       if (qla27xx_set_zio_threshold(base_vha,
+                           ha->nvme_last_rptd_aen)) {
                                ql_log(ql_log_info, base_vha, 0xffffff,
-                                       "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n",
-                                               ha->nvme_last_rptd_aen);
+                                   "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n",
+                                   ha->nvme_last_rptd_aen);
                        }
                }
 
+               if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED,
+                   &base_vha->dpc_flags)) {
+                       ql_log(ql_log_info, base_vha, 0xffffff,
+                           "SET ZIO Activity exchange threshold to %d.\n",
+                           ha->last_zio_threshold);
+                       qla27xx_set_zio_threshold(base_vha,
+                           ha->last_zio_threshold);
+               }
+
                if (!IS_QLAFX00(ha))
                        qla2x00_do_dpc_all_vps(base_vha);
 
         * FC-NVME
         * see if the active AEN count has changed from what was last reported.
         */
-       if (!vha->vp_idx &&
-               atomic_read(&ha->nvme_active_aen_cnt) != ha->nvme_last_rptd_aen &&
-               ha->zio_mode == QLA_ZIO_MODE_6) {
+       if (!vha->vp_idx && (atomic_read(&ha->nvme_active_aen_cnt) !=
+           ha->nvme_last_rptd_aen) && ha->zio_mode == QLA_ZIO_MODE_6) {
                ql_log(ql_log_info, vha, 0x3002,
-                       "nvme: Sched: Set ZIO exchange threshold to %d.\n",
-                       ha->nvme_last_rptd_aen);
+                   "nvme: Sched: Set ZIO exchange threshold to %d.\n",
+                   ha->nvme_last_rptd_aen);
                ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt);
+               set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags);
+               start_dpc++;
+       }
+
+       if (!vha->vp_idx &&
+           (atomic_read(&ha->zio_threshold) != ha->last_zio_threshold) &&
+           (ha->zio_mode == QLA_ZIO_MODE_6) &&
+           (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
+               ql_log(ql_log_info, vha, 0x3002,
+                   "Sched: Set ZIO exchange threshold to %d.\n",
+                   ha->last_zio_threshold);
+               ha->last_zio_threshold = atomic_read(&ha->zio_threshold);
                set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags);
                start_dpc++;
        }
 
                memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
                icb->firmware_options_1 |= cpu_to_le32(BIT_14);
        }
-
-       /* disable ZIO at start time. */
-       if (!vha->flags.init_done) {
-               uint32_t tmp;
-               tmp = le32_to_cpu(icb->firmware_options_2);
-               tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
-               icb->firmware_options_2 = cpu_to_le32(tmp);
-       }
 }
 
 void
                memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE);
                icb->firmware_options_1 |= cpu_to_le32(BIT_14);
        }
-
-       /* disable ZIO at start time. */
-       if (!vha->flags.init_done) {
-               uint32_t tmp;
-               tmp = le32_to_cpu(icb->firmware_options_2);
-               tmp &= ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
-               icb->firmware_options_2 = cpu_to_le32(tmp);
-       }
-
 }
 
 void