]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/qla2xxx/qla_target.c
scsi: qla2xxx: Add debug logging routine for qpair
[karo-tx-linux.git] / drivers / scsi / qla2xxx / qla_target.c
index 0e03ca2ab3e52358c817cdd2cdc667ba2bfb1ba3..0e8cdaa03ee4c0676accb3afefc6aa8ddbbadce9 100644 (file)
@@ -59,13 +59,20 @@ MODULE_PARM_DESC(qlini_mode,
        "when ready "
        "\"enabled\" (default) - initiator mode will always stay enabled.");
 
-static int ql_dm_tgt_ex_pct = 50;
+static int ql_dm_tgt_ex_pct = 0;
 module_param(ql_dm_tgt_ex_pct, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql_dm_tgt_ex_pct,
        "For Dual Mode (qlini_mode=dual), this parameter determines "
        "the percentage of exchanges/cmds FW will allocate resources "
        "for Target mode.");
 
+int ql2xuctrlirq = 1;
+module_param(ql2xuctrlirq, int, 0644);
+MODULE_PARM_DESC(ql2xuctrlirq,
+    "User to control IRQ placement via smp_affinity."
+    "Valid with qlini_mode=disabled."
+    "1(default): enable");
+
 int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
 
 static int temp_sam_status = SAM_STAT_BUSY;
@@ -110,18 +117,17 @@ enum fcp_resp_rsp_codes {
 /* Predefs for callbacks handed to qla2xxx LLD */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha,
        struct atio_from_isp *pkt, uint8_t);
-static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
+static void qlt_response_pkt(struct scsi_qla_host *ha, struct rsp_que *rsp,
+       response_t *pkt);
 static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun,
        int fn, void *iocb, int flags);
-static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
+static void qlt_send_term_exchange(struct qla_qpair *, struct qla_tgt_cmd
        *cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
-static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
-       struct qla_tgt_cmd *cmd);
 static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
        struct atio_from_isp *atio, uint16_t status, int qfull);
 static void qlt_disable_vha(struct scsi_qla_host *vha);
 static void qlt_clear_tgt_db(struct qla_tgt *tgt);
-static void qlt_send_notify_ack(struct scsi_qla_host *vha,
+static void qlt_send_notify_ack(struct qla_qpair *qpair,
        struct imm_ntfy_from_isp *ntfy,
        uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
        uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
@@ -132,6 +138,8 @@ static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha,
 void qlt_unreg_sess(struct fc_port *sess);
 static void qlt_24xx_handle_abts(struct scsi_qla_host *,
        struct abts_recv_from_24xx *);
+static void qlt_send_busy(struct qla_qpair *, struct atio_from_isp *,
+    uint16_t);
 
 /*
  * Global Variables
@@ -200,8 +208,8 @@ struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
 
        host = btree_lookup32(&vha->hw->tgt.host_map, key);
        if (!host)
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
-                          "Unable to find host %06x\n", key);
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005,
+                   "Unable to find host %06x\n", key);
 
        return host;
 }
@@ -245,26 +253,22 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
 
 
 static void qlt_queue_unknown_atio(scsi_qla_host_t *vha,
-       struct atio_from_isp *atio,     uint8_t ha_locked)
+       struct atio_from_isp *atio, uint8_t ha_locked)
 {
        struct qla_tgt_sess_op *u;
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        unsigned long flags;
 
        if (tgt->tgt_stop) {
-               ql_dbg(ql_dbg_async, vha, 0xffff,
-                          "qla_target(%d): dropping unknown ATIO_TYPE7, "
-                          "because tgt is being stopped", vha->vp_idx);
+               ql_dbg(ql_dbg_async, vha, 0x502c,
+                   "qla_target(%d): dropping unknown ATIO_TYPE7, because tgt is being stopped",
+                   vha->vp_idx);
                goto out_term;
        }
 
        u = kzalloc(sizeof(*u), GFP_ATOMIC);
-       if (u == NULL) {
-               ql_dbg(ql_dbg_async, vha, 0xffff,
-                   "Alloc of struct unknown_atio (size %zd) failed", sizeof(*u));
-               /* It should be harmless and on the next retry should work well */
+       if (u == NULL)
                goto out_term;
-       }
 
        u->vha = vha;
        memcpy(&u->atio, atio, sizeof(*atio));
@@ -280,7 +284,7 @@ out:
        return;
 
 out_term:
-       qlt_send_term_exchange(vha, NULL, atio, ha_locked, 0);
+       qlt_send_term_exchange(vha->hw->base_qpair, NULL, atio, ha_locked, 0);
        goto out;
 }
 
@@ -295,29 +299,28 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha,
 
        list_for_each_entry_safe(u, t, &vha->unknown_atio_list, cmd_list) {
                if (u->aborted) {
-                       ql_dbg(ql_dbg_async, vha, 0xffff,
-                           "Freeing unknown %s %p, because of Abort",
+                       ql_dbg(ql_dbg_async, vha, 0x502e,
+                           "Freeing unknown %s %p, because of Abort\n",
                            "ATIO_TYPE7", u);
-                       qlt_send_term_exchange(vha, NULL, &u->atio,
-                           ha_locked, 0);
+                       qlt_send_term_exchange(vha->hw->base_qpair, NULL,
+                           &u->atio, ha_locked, 0);
                        goto abort;
                }
 
                host = qlt_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id);
                if (host != NULL) {
-                       ql_dbg(ql_dbg_async, vha, 0xffff,
-                               "Requeuing unknown ATIO_TYPE7 %p", u);
+                       ql_dbg(ql_dbg_async, vha, 0x502f,
+                           "Requeuing unknown ATIO_TYPE7 %p\n", u);
                        qlt_24xx_atio_pkt(host, &u->atio, ha_locked);
                } else if (tgt->tgt_stop) {
-                       ql_dbg(ql_dbg_async, vha, 0xffff,
-                               "Freeing unknown %s %p, because tgt is being stopped",
-                               "ATIO_TYPE7", u);
-                       qlt_send_term_exchange(vha, NULL, &u->atio,
-                           ha_locked, 0);
+                       ql_dbg(ql_dbg_async, vha, 0x503a,
+                           "Freeing unknown %s %p, because tgt is being stopped\n",
+                           "ATIO_TYPE7", u);
+                       qlt_send_term_exchange(vha->hw->base_qpair, NULL,
+                           &u->atio, ha_locked, 0);
                } else {
-                       ql_dbg(ql_dbg_async, vha, 0xffff,
-                               "u %p, vha %p, host %p, sched again..", u,
-                               vha, host);
+                       ql_dbg(ql_dbg_async, vha, 0x503d,
+                           "Reschedule u %p, vha %p, host %p\n", u, vha, host);
                        if (!queued) {
                                queued = 1;
                                schedule_delayed_work(&vha->unknown_atio_work,
@@ -380,6 +383,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
                struct imm_ntfy_from_isp *entry =
                    (struct imm_ntfy_from_isp *)atio;
 
+               qlt_issue_marker(vha, ha_locked);
+
                if ((entry->u.isp24.vp_index != 0xFF) &&
                    (entry->u.isp24.nport_handle != 0xFFFF)) {
                        host = qlt_find_host_by_vp_idx(vha,
@@ -411,7 +416,7 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
                unsigned long flags;
 
                if (unlikely(!host)) {
-                       ql_dbg(ql_dbg_tgt, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt, vha, 0xe00a,
                            "qla_target(%d): Response pkt (ABTS_RECV_24XX) "
                            "received, with unknown vp_index %d\n",
                            vha->vp_idx, entry->vp_index);
@@ -437,7 +442,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
        return false;
 }
 
-void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
+void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
+       struct rsp_que *rsp, response_t *pkt)
 {
        switch (pkt->entry_type) {
        case CTIO_CRC2:
@@ -456,7 +462,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
                            vha->vp_idx, entry->vp_index);
                        break;
                }
-               qlt_response_pkt(host, pkt);
+               qlt_response_pkt(host, rsp, pkt);
                break;
        }
 
@@ -474,7 +480,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
                            vha->vp_idx, entry->u.isp24.vp_index);
                        break;
                }
-               qlt_response_pkt(host, pkt);
+               qlt_response_pkt(host, rsp, pkt);
                break;
        }
 
@@ -496,7 +502,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
                                break;
                        }
                }
-               qlt_response_pkt(host, pkt);
+               qlt_response_pkt(host, rsp, pkt);
                break;
        }
 
@@ -513,7 +519,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
                            "vp_index %d\n", vha->vp_idx, entry->vp_index);
                        break;
                }
-               qlt_response_pkt(host, pkt);
+               qlt_response_pkt(host, rsp, pkt);
                break;
        }
 
@@ -530,12 +536,12 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
                            "vp_index %d\n", vha->vp_idx, entry->vp_index);
                        break;
                }
-               qlt_response_pkt(host, pkt);
+               qlt_response_pkt(host, rsp, pkt);
                break;
        }
 
        default:
-               qlt_response_pkt(vha, pkt);
+               qlt_response_pkt(vha, rsp, pkt);
                break;
        }
 
@@ -565,13 +571,13 @@ void qla2x00_async_nack_sp_done(void *s, int res)
        struct scsi_qla_host *vha = sp->vha;
        unsigned long flags;
 
-       ql_dbg(ql_dbg_disc, vha, 0xffff,
-               "Async done-%s res %x %8phC  type %d\n",
-               sp->name, res, sp->fcport->port_name, sp->type);
+       ql_dbg(ql_dbg_disc, vha, 0x20f2,
+           "Async done-%s res %x %8phC  type %d\n",
+           sp->name, res, sp->fcport->port_name, sp->type);
 
        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
        sp->fcport->flags &= ~FCF_ASYNC_SENT;
-       sp->fcport->chip_reset = vha->hw->chip_reset;
+       sp->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
 
        switch (sp->type) {
        case SRB_NACK_PLOGI:
@@ -593,19 +599,19 @@ void qla2x00_async_nack_sp_done(void *s, int res)
 
                        if (!IS_IIDMA_CAPABLE(vha->hw) ||
                            !vha->hw->flags.gpsc_supported) {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
-                                       "%s %d %8phC post upd_fcport fcp_cnt %d\n",
-                                       __func__, __LINE__,
-                                       sp->fcport->port_name,
-                                       vha->fcport_count);
+                               ql_dbg(ql_dbg_disc, vha, 0x20f3,
+                                   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
+                                   __func__, __LINE__,
+                                   sp->fcport->port_name,
+                                   vha->fcport_count);
 
                                qla24xx_post_upd_fcport_work(vha, sp->fcport);
                        } else {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
-                                       "%s %d %8phC post gpsc fcp_cnt %d\n",
-                                       __func__, __LINE__,
-                                       sp->fcport->port_name,
-                                       vha->fcport_count);
+                               ql_dbg(ql_dbg_disc, vha, 0x20f5,
+                                   "%s %d %8phC post gpsc fcp_cnt %d\n",
+                                   __func__, __LINE__,
+                                   sp->fcport->port_name,
+                                   vha->fcport_count);
 
                                qla24xx_post_gpsc_work(vha, sp->fcport);
                        }
@@ -664,9 +670,9 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
        if (rval != QLA_SUCCESS)
                goto done_free_sp;
 
-       ql_dbg(ql_dbg_disc, vha, 0xffff,
-               "Async-%s %8phC hndl %x %s\n",
-               sp->name, fcport->port_name, sp->handle, c);
+       ql_dbg(ql_dbg_disc, vha, 0x20f4,
+           "Async-%s %8phC hndl %x %s\n",
+           sp->name, fcport->port_name, sp->handle, c);
 
        return rval;
 
@@ -688,7 +694,7 @@ void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
                t = qlt_create_sess(vha, e->u.nack.fcport, 0);
                mutex_unlock(&vha->vha_tgt.tgt_mutex);
                if (t) {
-                       ql_log(ql_log_info, vha, 0xffff,
+                       ql_log(ql_log_info, vha, 0xd034,
                            "%s create sess success %p", __func__, t);
                        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
                        /* create sess has an extra kref */
@@ -757,7 +763,7 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
                }
 
                if (!kref_get_unless_zero(&sess->sess_kref)) {
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0x2107,
                            "%s: kref_get fail sess %8phC \n",
                            __func__, sess->port_name);
                        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
@@ -1026,7 +1032,7 @@ static void qlt_free_session_done(struct work_struct *work)
                sess->login_succ = 0;
        }
 
-       if (sess->chip_reset != sess->vha->hw->chip_reset)
+       if (sess->chip_reset != ha->base_qpair->chip_reset)
                qla2x00_clear_loop_id(sess);
 
        if (sess->conflict) {
@@ -1098,7 +1104,7 @@ void qlt_unreg_sess(struct fc_port *sess)
 {
        struct scsi_qla_host *vha = sess->vha;
 
-       ql_dbg(ql_dbg_disc, sess->vha, 0xffff,
+       ql_dbg(ql_dbg_disc, sess->vha, 0x210a,
            "%s sess %p for deletion %8phC\n",
            __func__, sess, sess->port_name);
 
@@ -1156,7 +1162,7 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
 
 static void qla24xx_chk_fcp_state(struct fc_port *sess)
 {
-       if (sess->chip_reset != sess->vha->hw->chip_reset) {
+       if (sess->chip_reset != sess->vha->hw->base_qpair->chip_reset) {
                sess->logout_on_delete = 0;
                sess->logo_ack_needed = 0;
                sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
@@ -1288,7 +1294,7 @@ static struct fc_port *qlt_create_sess(
 
        if (fcport->se_sess) {
                if (!kref_get_unless_zero(&sess->sess_kref)) {
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0x20f6,
                            "%s: kref_get_unless_zero failed for %8phC\n",
                            __func__, sess->port_name);
                        return NULL;
@@ -1310,7 +1316,7 @@ static struct fc_port *qlt_create_sess(
 
        if (ha->tgt.tgt_ops->check_initiator_node_acl(vha,
            &fcport->port_name[0], sess) < 0) {
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf015,
                    "(%d) %8phC check_initiator_node_acl failed\n",
                    vha->vp_idx, fcport->port_name);
                return NULL;
@@ -1321,7 +1327,7 @@ static struct fc_port *qlt_create_sess(
                 * fc_port access across ->tgt.sess_lock reaquire.
                 */
                if (!kref_get_unless_zero(&sess->sess_kref)) {
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0x20f7,
                            "%s: kref_get_unless_zero failed for %8phC\n",
                            __func__, sess->port_name);
                        return NULL;
@@ -1432,6 +1438,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
 
                if (npiv_vports) {
                        mutex_unlock(&qla_tgt_mutex);
+                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021,
+                           "NPIV is in use. Can not stop target\n");
                        return -EPERM;
                }
        }
@@ -1442,7 +1450,7 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
                return -EPERM;
        }
 
-       ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n",
+       ql_dbg(ql_dbg_tgt_mgt, vha, 0xe003, "Stopping target for host %ld(%p)\n",
            vha->host_no, vha);
        /*
         * Mutex needed to sync with qla_tgt_fc_port_[added,deleted].
@@ -1485,9 +1493,7 @@ EXPORT_SYMBOL(qlt_stop_phase1);
 /* Called by tcm_qla2xxx configfs code */
 void qlt_stop_phase2(struct qla_tgt *tgt)
 {
-       struct qla_hw_data *ha = tgt->ha;
-       scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
-       unsigned long flags;
+       scsi_qla_host_t *vha = tgt->vha;
 
        if (tgt->tgt_stopped) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04f,
@@ -1495,24 +1501,19 @@ void qlt_stop_phase2(struct qla_tgt *tgt)
                dump_stack();
                return;
        }
-
-       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
-           "Waiting for %d IRQ commands to complete (tgt %p)",
-           tgt->irq_cmd_count, tgt);
+       if (!tgt->tgt_stop) {
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b,
+                   "%s: phase1 stop is not completed\n", __func__);
+               dump_stack();
+               return;
+       }
 
        mutex_lock(&vha->vha_tgt.tgt_mutex);
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) {
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
-               udelay(2);
-               spin_lock_irqsave(&ha->hardware_lock, flags);
-       }
        tgt->tgt_stop = 0;
        tgt->tgt_stopped = 1;
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
        mutex_unlock(&vha->vha_tgt.tgt_mutex);
 
-       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished",
+       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n",
            tgt);
 }
 EXPORT_SYMBOL(qlt_stop_phase2);
@@ -1521,10 +1522,36 @@ EXPORT_SYMBOL(qlt_stop_phase2);
 static void qlt_release(struct qla_tgt *tgt)
 {
        scsi_qla_host_t *vha = tgt->vha;
+       void *node;
+       u64 key = 0;
+       u16 i;
+       struct qla_qpair_hint *h;
+
+       if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stop &&
+           !tgt->tgt_stopped)
+               qlt_stop_phase1(tgt);
 
        if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stopped)
                qlt_stop_phase2(tgt);
 
+       for (i = 0; i < vha->hw->max_qpairs + 1; i++) {
+               unsigned long flags;
+
+               h = &tgt->qphints[i];
+               if (h->qpair) {
+                       spin_lock_irqsave(h->qpair->qp_lock_ptr, flags);
+                       list_del(&h->hint_elem);
+                       spin_unlock_irqrestore(h->qpair->qp_lock_ptr, flags);
+                       h->qpair = NULL;
+               }
+       }
+       kfree(tgt->qphints);
+
+       btree_for_each_safe64(&tgt->lun_qpair_map, key, node)
+               btree_remove64(&tgt->lun_qpair_map, key);
+
+       btree_destroy64(&tgt->lun_qpair_map);
+
        vha->vha_tgt.qla_tgt = NULL;
 
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00d,
@@ -1568,11 +1595,12 @@ static int qlt_sched_sess_work(struct qla_tgt *tgt, int type,
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static void qlt_send_notify_ack(struct scsi_qla_host *vha,
+static void qlt_send_notify_ack(struct qla_qpair *qpair,
        struct imm_ntfy_from_isp *ntfy,
        uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
        uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan)
 {
+       struct scsi_qla_host *vha = qpair->vha;
        struct qla_hw_data *ha = vha->hw;
        request_t *pkt;
        struct nack_to_isp *nack;
@@ -1582,11 +1610,7 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
 
        ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha);
 
-       /* Send marker if required */
-       if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
-               return;
-
-       pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
+       pkt = (request_t *)__qla2x00_alloc_iocbs(qpair, NULL);
        if (!pkt) {
                ql_dbg(ql_dbg_tgt, vha, 0xe049,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -1627,16 +1651,17 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha,
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
+       qla2x00_start_iocbs(vha, qpair->req);
 }
 
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
+static void qlt_24xx_send_abts_resp(struct qla_qpair *qpair,
        struct abts_recv_from_24xx *abts, uint32_t status,
        bool ids_reversed)
 {
+       struct scsi_qla_host *vha = qpair->vha;
        struct qla_hw_data *ha = vha->hw;
        struct abts_resp_to_24xx *resp;
        uint32_t f_ctl;
@@ -1646,11 +1671,8 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
            "Sending task mgmt ABTS response (ha=%p, atio=%p, status=%x\n",
            ha, abts, status);
 
-       /* Send marker if required */
-       if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
-               return;
-
-       resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
+       resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs_ready(qpair,
+           NULL);
        if (!resp) {
                ql_dbg(ql_dbg_tgt, vha, 0xe04a,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -1706,7 +1728,10 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha,
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
 }
 
 /*
@@ -1719,11 +1744,9 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
 
        ql_dbg(ql_dbg_tgt, vha, 0xe007,
            "Sending retry TERM EXCH CTIO7 (ha=%p)\n", vha->hw);
-       /* Send marker if required */
-       if (qlt_issue_marker(vha, 1) != QLA_SUCCESS)
-               return;
 
-       ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(vha, NULL);
+       ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs_ready(
+           vha->hw->base_qpair, NULL);
        if (ctio == NULL) {
                ql_dbg(ql_dbg_tgt, vha, 0xe04b,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -1754,7 +1777,8 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
        wmb();
        qla2x00_start_iocbs(vha, vha->req);
 
-       qlt_24xx_send_abts_resp(vha, (struct abts_recv_from_24xx *)entry,
+       qlt_24xx_send_abts_resp(vha->hw->base_qpair,
+           (struct abts_recv_from_24xx *)entry,
            FCP_TMF_CMPL, true);
 }
 
@@ -1762,13 +1786,13 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
 {
        struct qla_tgt_sess_op *op;
        struct qla_tgt_cmd *cmd;
+       unsigned long flags;
 
-       spin_lock(&vha->cmd_list_lock);
-
+       spin_lock_irqsave(&vha->cmd_list_lock, flags);
        list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
                if (tag == op->atio.u.isp24.exchange_addr) {
                        op->aborted = true;
-                       spin_unlock(&vha->cmd_list_lock);
+                       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
                        return 1;
                }
        }
@@ -1776,7 +1800,7 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
        list_for_each_entry(op, &vha->unknown_atio_list, cmd_list) {
                if (tag == op->atio.u.isp24.exchange_addr) {
                        op->aborted = true;
-                       spin_unlock(&vha->cmd_list_lock);
+                       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
                        return 1;
                }
        }
@@ -1784,12 +1808,12 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
        list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
                if (tag == cmd->atio.u.isp24.exchange_addr) {
                        cmd->aborted = 1;
-                       spin_unlock(&vha->cmd_list_lock);
+                       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
                        return 1;
                }
        }
+       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 
-       spin_unlock(&vha->cmd_list_lock);
        return 0;
 }
 
@@ -1799,17 +1823,18 @@ static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
  *     for the same lun)
  */
 static void abort_cmds_for_lun(struct scsi_qla_host *vha,
-                               uint32_t lun, uint8_t *s_id)
+                               u64 lun, uint8_t *s_id)
 {
        struct qla_tgt_sess_op *op;
        struct qla_tgt_cmd *cmd;
        uint32_t key;
+       unsigned long flags;
 
        key = sid_to_key(s_id);
-       spin_lock(&vha->cmd_list_lock);
+       spin_lock_irqsave(&vha->cmd_list_lock, flags);
        list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
                uint32_t op_key;
-               uint32_t op_lun;
+               u64 op_lun;
 
                op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
                op_lun = scsilun_to_int(
@@ -1831,7 +1856,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
 
        list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
                uint32_t cmd_key;
-               uint32_t cmd_lun;
+               u64 cmd_lun;
 
                cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
                cmd_lun = scsilun_to_int(
@@ -1839,7 +1864,7 @@ static void abort_cmds_for_lun(struct scsi_qla_host *vha,
                if (cmd_key == key && cmd_lun == lun)
                        cmd->aborted = 1;
        }
-       spin_unlock(&vha->cmd_list_lock);
+       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -1849,18 +1874,15 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
        struct qla_hw_data *ha = vha->hw;
        struct se_session *se_sess = sess->se_sess;
        struct qla_tgt_mgmt_cmd *mcmd;
+       struct qla_tgt_cmd *cmd;
        struct se_cmd *se_cmd;
-       u32 lun = 0;
        int rc;
        bool found_lun = false;
        unsigned long flags;
 
        spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
        list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
-               struct qla_tgt_cmd *cmd =
-                       container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
                if (se_cmd->tag == abts->exchange_addr_to_abort) {
-                       lun = cmd->unpacked_lun;
                        found_lun = true;
                        break;
                }
@@ -1871,7 +1893,8 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
        if (!found_lun) {
                if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
                        /* send TASK_ABORT response immediately */
-                       qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
+                       qlt_24xx_send_abts_resp(ha->base_qpair, abts,
+                           FCP_TMF_CMPL, false);
                        return 0;
                } else {
                        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
@@ -1894,12 +1917,14 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
        }
        memset(mcmd, 0, sizeof(*mcmd));
 
+       cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
        mcmd->sess = sess;
        memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
-       mcmd->reset_count = vha->hw->chip_reset;
+       mcmd->reset_count = ha->base_qpair->chip_reset;
        mcmd->tmr_func = QLA_TGT_ABTS;
+       mcmd->qpair = ha->base_qpair;
 
-       rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+       rc = ha->tgt.tgt_ops->handle_tmr(mcmd, cmd->unpacked_lun, mcmd->tmr_func,
            abts->exchange_addr_to_abort);
        if (rc != 0) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
@@ -1929,7 +1954,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053,
                    "qla_target(%d): ABTS: Abort Sequence not "
                    "supported\n", vha->vp_idx);
-               qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
+               qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
+                   false);
                return;
        }
 
@@ -1937,7 +1963,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf010,
                    "qla_target(%d): ABTS: Unknown Exchange "
                    "Address received\n", vha->vp_idx);
-               qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
+               qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
+                   false);
                return;
        }
 
@@ -1963,8 +1990,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
                spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
                if (rc != 0) {
-                       qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED,
-                           false);
+                       qlt_24xx_send_abts_resp(ha->base_qpair, abts,
+                           FCP_TMF_REJECTED, false);
                }
                return;
        }
@@ -1972,7 +1999,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
 
 
        if (sess->deleted) {
-               qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
+               qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
+                   false);
                return;
        }
 
@@ -1981,7 +2009,8 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054,
                    "qla_target(%d): __qlt_24xx_handle_abts() failed: %d\n",
                    vha->vp_idx, rc);
-               qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
+               qlt_24xx_send_abts_resp(ha->base_qpair, abts, FCP_TMF_REJECTED,
+                   false);
                return;
        }
 }
@@ -1989,9 +2018,10 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
+static void qlt_24xx_send_task_mgmt_ctio(struct qla_qpair *qpair,
        struct qla_tgt_mgmt_cmd *mcmd, uint32_t resp_code)
 {
+       struct scsi_qla_host *ha = qpair->vha;
        struct atio_from_isp *atio = &mcmd->orig_iocb.atio;
        struct ctio7_to_24xx *ctio;
        uint16_t temp;
@@ -2000,11 +2030,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
            "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n",
            ha, atio, resp_code);
 
-       /* Send marker if required */
-       if (qlt_issue_marker(ha, 1) != QLA_SUCCESS)
-               return;
 
-       ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(ha, NULL);
+       ctio = (struct ctio7_to_24xx *)__qla2x00_alloc_iocbs(qpair, NULL);
        if (ctio == NULL) {
                ql_dbg(ql_dbg_tgt, ha, 0xe04c,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -2022,8 +2049,9 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
        ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
        ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
        ctio->exchange_addr = atio->u.isp24.exchange_addr;
-       ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-           cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+       temp = (atio->u.isp24.attr << 9)|
+               CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+       ctio->u.status1.flags = cpu_to_le16(temp);
        temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
        ctio->u.status1.ox_id = cpu_to_le16(temp);
        ctio->u.status1.scsi_status =
@@ -2033,7 +2061,10 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(ha, ha->req);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(ha, qpair->req);
 }
 
 void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
@@ -2046,12 +2077,13 @@ EXPORT_SYMBOL(qlt_free_mcmd);
  * ha->hardware_lock supposed to be held on entry. Might drop it, then
  * reacquire
  */
-void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
+void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd,
     uint8_t scsi_status, uint8_t sense_key, uint8_t asc, uint8_t ascq)
 {
        struct atio_from_isp *atio = &cmd->atio;
        struct ctio7_to_24xx *ctio;
        uint16_t temp;
+       struct scsi_qla_host *vha = cmd->vha;
 
        ql_dbg(ql_dbg_tgt_dif, vha, 0x3066,
            "Sending response CTIO7 (vha=%p, atio=%p, scsi_status=%02x, "
@@ -2076,8 +2108,9 @@ void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
        ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
        ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
        ctio->exchange_addr = atio->u.isp24.exchange_addr;
-       ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
-           cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS);
+       temp = (atio->u.isp24.attr << 9) |
+           CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS;
+       ctio->u.status1.flags = cpu_to_le16(temp);
        temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
        ctio->u.status1.ox_id = cpu_to_le16(temp);
        ctio->u.status1.scsi_status =
@@ -2101,7 +2134,11 @@ void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
        /* Memory Barrier */
        wmb();
 
-       qla2x00_start_iocbs(vha, vha->req);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
+
 out:
        return;
 }
@@ -2112,14 +2149,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
        struct scsi_qla_host *vha = mcmd->sess->vha;
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags;
+       struct qla_qpair *qpair = mcmd->qpair;
 
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf013,
            "TM response mcmd (%p) status %#x state %#x",
            mcmd, mcmd->fc_tm_rsp, mcmd->flags);
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
 
-       if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) {
+       if (!vha->flags.online || mcmd->reset_count != qpair->chip_reset) {
                /*
                 * Either the port is not online or this request was from
                 * previous life, just abort the processing.
@@ -2127,9 +2165,9 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
                ql_dbg(ql_dbg_async, vha, 0xe100,
                        "RESET-TMR online/active/old-count/new-count = %d/%d/%d/%d.\n",
                        vha->flags.online, qla2x00_reset_active(vha),
-                       mcmd->reset_count, ha->chip_reset);
+                       mcmd->reset_count, qpair->chip_reset);
                ha->tgt.tgt_ops->free_mcmd(mcmd);
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
                return;
        }
 
@@ -2140,21 +2178,21 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
                    ELS_PRLO ||
                    mcmd->orig_iocb.imm_ntfy.u.isp24.status_subcode ==
                    ELS_TPRLO) {
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0x2106,
                            "TM response logo %phC status %#x state %#x",
                            mcmd->sess->port_name, mcmd->fc_tm_rsp,
                            mcmd->flags);
                        qlt_schedule_sess_for_deletion_lock(mcmd->sess);
                } else {
-                       qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy,
-                               0, 0, 0, 0, 0, 0);
+                       qlt_send_notify_ack(vha->hw->base_qpair,
+                           &mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0);
                }
        } else {
                if (mcmd->orig_iocb.atio.u.raw.entry_type == ABTS_RECV_24XX)
-                       qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts,
+                       qlt_24xx_send_abts_resp(qpair, &mcmd->orig_iocb.abts,
                            mcmd->fc_tm_rsp, false);
                else
-                       qlt_24xx_send_task_mgmt_ctio(vha, mcmd,
+                       qlt_24xx_send_task_mgmt_ctio(qpair, mcmd,
                            mcmd->fc_tm_rsp);
        }
        /*
@@ -2166,7 +2204,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
         * qlt_xmit_tm_rsp() returns here..
         */
        ha->tgt.tgt_ops->free_mcmd(mcmd);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 }
 EXPORT_SYMBOL(qlt_xmit_tm_rsp);
 
@@ -2178,7 +2216,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
        BUG_ON(cmd->sg_cnt == 0);
 
        prm->sg = (struct scatterlist *)cmd->sg;
-       prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, cmd->sg,
+       prm->seg_cnt = pci_map_sg(cmd->qpair->pdev, cmd->sg,
            cmd->sg_cnt, cmd->dma_data_direction);
        if (unlikely(prm->seg_cnt == 0))
                goto out_err;
@@ -2205,7 +2243,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
 
                if (cmd->prot_sg_cnt) {
                        prm->prot_sg      = cmd->prot_sg;
-                       prm->prot_seg_cnt = pci_map_sg(prm->tgt->ha->pdev,
+                       prm->prot_seg_cnt = pci_map_sg(cmd->qpair->pdev,
                                cmd->prot_sg, cmd->prot_sg_cnt,
                                cmd->dma_data_direction);
                        if (unlikely(prm->prot_seg_cnt == 0))
@@ -2225,7 +2263,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
        return 0;
 
 out_err:
-       ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe04d,
+       ql_dbg_qp(ql_dbg_tgt, prm->cmd->qpair, 0xe04d,
            "qla_target(%d): PCI mapping failed: sg_cnt=%d",
            0, prm->cmd->sg_cnt);
        return -1;
@@ -2233,51 +2271,50 @@ out_err:
 
 static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
 {
-       struct qla_hw_data *ha = vha->hw;
-
+       struct qla_hw_data *ha;
+       struct qla_qpair *qpair;
        if (!cmd->sg_mapped)
                return;
 
-       pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
+       qpair = cmd->qpair;
+
+       pci_unmap_sg(qpair->pdev, cmd->sg, cmd->sg_cnt,
+           cmd->dma_data_direction);
        cmd->sg_mapped = 0;
 
        if (cmd->prot_sg_cnt)
-               pci_unmap_sg(ha->pdev, cmd->prot_sg, cmd->prot_sg_cnt,
+               pci_unmap_sg(qpair->pdev, cmd->prot_sg, cmd->prot_sg_cnt,
                        cmd->dma_data_direction);
 
+       if (!cmd->ctx)
+               return;
+       ha = vha->hw;
        if (cmd->ctx_dsd_alloced)
-               qla2x00_clean_dsd_pool(ha, NULL, cmd);
+               qla2x00_clean_dsd_pool(ha, cmd->ctx);
 
-       if (cmd->ctx)
-               dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);
+       dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);
 }
 
-static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
+static int qlt_check_reserve_free_req(struct qla_qpair *qpair,
        uint32_t req_cnt)
 {
-       uint32_t cnt, cnt_in;
+       uint32_t cnt;
+       struct req_que *req = qpair->req;
 
-       if (vha->req->cnt < (req_cnt + 2)) {
-               cnt = (uint16_t)RD_REG_DWORD(vha->req->req_q_out);
-               cnt_in = (uint16_t)RD_REG_DWORD(vha->req->req_q_in);
+       if (req->cnt < (req_cnt + 2)) {
+               cnt = (uint16_t)(qpair->use_shadow_reg ? *req->out_ptr :
+                   RD_REG_DWORD_RELAXED(req->req_q_out));
 
-               if  (vha->req->ring_index < cnt)
-                       vha->req->cnt = cnt - vha->req->ring_index;
+               if  (req->ring_index < cnt)
+                       req->cnt = cnt - req->ring_index;
                else
-                       vha->req->cnt = vha->req->length -
-                           (vha->req->ring_index - cnt);
-
-               if (unlikely(vha->req->cnt < (req_cnt + 2))) {
-                       ql_dbg(ql_dbg_io, vha, 0x305a,
-                           "qla_target(%d): There is no room in the request ring: vha->req->ring_index=%d, vha->req->cnt=%d, req_cnt=%d Req-out=%d Req-in=%d Req-Length=%d\n",
-                           vha->vp_idx, vha->req->ring_index,
-                           vha->req->cnt, req_cnt, cnt, cnt_in,
-                           vha->req->length);
+                       req->cnt = req->length - (req->ring_index - cnt);
+
+               if (unlikely(req->cnt < (req_cnt + 2)))
                        return -EAGAIN;
-               }
        }
 
-       vha->req->cnt -= req_cnt;
+       req->cnt -= req_cnt;
 
        return 0;
 }
@@ -2285,67 +2322,73 @@ static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static inline void *qlt_get_req_pkt(struct scsi_qla_host *vha)
+static inline void *qlt_get_req_pkt(struct req_que *req)
 {
        /* Adjust ring index. */
-       vha->req->ring_index++;
-       if (vha->req->ring_index == vha->req->length) {
-               vha->req->ring_index = 0;
-               vha->req->ring_ptr = vha->req->ring;
+       req->ring_index++;
+       if (req->ring_index == req->length) {
+               req->ring_index = 0;
+               req->ring_ptr = req->ring;
        } else {
-               vha->req->ring_ptr++;
+               req->ring_ptr++;
        }
-       return (cont_entry_t *)vha->req->ring_ptr;
+       return (cont_entry_t *)req->ring_ptr;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
-static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha)
+static inline uint32_t qlt_make_handle(struct qla_qpair *qpair)
 {
-       struct qla_hw_data *ha = vha->hw;
        uint32_t h;
+       int index;
+       uint8_t found = 0;
+       struct req_que *req = qpair->req;
+
+       h = req->current_outstanding_cmd;
+
+       for (index = 1; index < req->num_outstanding_cmds; index++) {
+               h++;
+               if (h == req->num_outstanding_cmds)
+                       h = 1;
 
-       h = ha->tgt.current_handle;
-       /* always increment cmd handle */
-       do {
-               ++h;
-               if (h > DEFAULT_OUTSTANDING_COMMANDS)
-                       h = 1; /* 0 is QLA_TGT_NULL_HANDLE */
-               if (h == ha->tgt.current_handle) {
-                       ql_dbg(ql_dbg_io, vha, 0x305b,
-                           "qla_target(%d): Ran out of "
-                           "empty cmd slots in ha %p\n", vha->vp_idx, ha);
-                       h = QLA_TGT_NULL_HANDLE;
+               if (h == QLA_TGT_SKIP_HANDLE)
+                       continue;
+
+               if (!req->outstanding_cmds[h]) {
+                       found = 1;
                        break;
                }
-       } while ((h == QLA_TGT_NULL_HANDLE) ||
-           (h == QLA_TGT_SKIP_HANDLE) ||
-           (ha->tgt.cmds[h-1] != NULL));
+       }
 
-       if (h != QLA_TGT_NULL_HANDLE)
-               ha->tgt.current_handle = h;
+       if (found) {
+               req->current_outstanding_cmd = h;
+       } else {
+               ql_dbg(ql_dbg_io, qpair->vha, 0x305b,
+                   "qla_target(%d): Ran out of empty cmd slots\n",
+                   qpair->vha->vp_idx);
+               h = QLA_TGT_NULL_HANDLE;
+       }
 
        return h;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
-static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
-       struct scsi_qla_host *vha)
+static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
+       struct qla_tgt_prm *prm)
 {
        uint32_t h;
        struct ctio7_to_24xx *pkt;
-       struct qla_hw_data *ha = vha->hw;
        struct atio_from_isp *atio = &prm->cmd->atio;
        uint16_t temp;
 
-       pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr;
+       pkt = (struct ctio7_to_24xx *)qpair->req->ring_ptr;
        prm->pkt = pkt;
        memset(pkt, 0, sizeof(*pkt));
 
        pkt->entry_type = CTIO_TYPE7;
        pkt->entry_count = (uint8_t)prm->req_cnt;
-       pkt->vp_index = vha->vp_idx;
+       pkt->vp_index = prm->cmd->vp_idx;
 
-       h = qlt_make_handle(vha);
+       h = qlt_make_handle(qpair);
        if (unlikely(h == QLA_TGT_NULL_HANDLE)) {
                /*
                 * CTIO type 7 from the firmware doesn't provide a way to
@@ -2354,16 +2397,18 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
                 */
                return -EAGAIN;
        } else
-               ha->tgt.cmds[h - 1] = prm->cmd;
+               qpair->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
 
-       pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
-       pkt->nport_handle = prm->cmd->loop_id;
+       pkt->handle = MAKE_HANDLE(qpair->req->id, h);
+       pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
+       pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
        pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
        pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
        pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
        pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
        pkt->exchange_addr = atio->u.isp24.exchange_addr;
-       pkt->u.status0.flags |= (atio->u.isp24.attr << 9);
+       temp = atio->u.isp24.attr << 9;
+       pkt->u.status0.flags |= cpu_to_le16(temp);
        temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
        pkt->u.status0.ox_id = cpu_to_le16(temp);
        pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
@@ -2385,7 +2430,8 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm,
        /* Build continuation packets */
        while (prm->seg_cnt > 0) {
                cont_a64_entry_t *cont_pkt64 =
-                       (cont_a64_entry_t *)qlt_get_req_pkt(vha);
+                       (cont_a64_entry_t *)qlt_get_req_pkt(
+                          prm->cmd->qpair->req);
 
                /*
                 * Make sure that from cont_pkt64 none of
@@ -2496,35 +2542,35 @@ static void qlt_print_dif_err(struct qla_tgt_prm *prm)
                /* ASCQ */
                switch (prm->sense_buffer[13]) {
                case 1:
-                       ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_dif, vha, 0xe00b,
                            "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] "
                            "se_cmd=%p tag[%x]",
                            cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
                            cmd->atio.u.isp24.exchange_addr);
                        break;
                case 2:
-                       ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_dif, vha, 0xe00c,
                            "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] "
                            "se_cmd=%p tag[%x]",
                            cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
                            cmd->atio.u.isp24.exchange_addr);
                        break;
                case 3:
-                       ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_dif, vha, 0xe00f,
                            "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] "
                            "se_cmd=%p tag[%x]",
                            cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
                            cmd->atio.u.isp24.exchange_addr);
                        break;
                default:
-                       ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_dif, vha, 0xe010,
                            "BE detected Dif ERR: lba[%llx|%lld] len[%x] "
                            "se_cmd=%p tag[%x]",
                            cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd,
                            cmd->atio.u.isp24.exchange_addr);
                        break;
                }
-               ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xffff, cmd->cdb, 16);
+               ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xe011, cmd->cdb, 16);
        }
 }
 
@@ -2535,24 +2581,23 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
        struct qla_tgt_prm *prm, int xmit_type, uint8_t scsi_status,
        uint32_t *full_req_cnt)
 {
-       struct qla_tgt *tgt = cmd->tgt;
-       struct scsi_qla_host *vha = tgt->vha;
-       struct qla_hw_data *ha = vha->hw;
        struct se_cmd *se_cmd = &cmd->se_cmd;
+       struct qla_qpair *qpair = cmd->qpair;
 
        prm->cmd = cmd;
-       prm->tgt = tgt;
+       prm->tgt = cmd->tgt;
+       prm->pkt = NULL;
        prm->rq_result = scsi_status;
        prm->sense_buffer = &cmd->sense_buffer[0];
        prm->sense_buffer_len = TRANSPORT_SENSE_BUFFER;
        prm->sg = NULL;
        prm->seg_cnt = -1;
        prm->req_cnt = 1;
+       prm->residual = 0;
        prm->add_status_pkt = 0;
-
-       /* Send marker if required */
-       if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
-               return -EFAULT;
+       prm->prot_sg = NULL;
+       prm->prot_seg_cnt = 0;
+       prm->tot_dsds = 0;
 
        if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) {
                if  (qlt_pci_map_calc_cnt(prm) != 0)
@@ -2563,7 +2608,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
 
        if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
                prm->residual = se_cmd->residual_count;
-               ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x305c,
+               ql_dbg_qp(ql_dbg_io + ql_dbg_verbose, qpair, 0x305c,
                    "Residual underflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
                       prm->residual, se_cmd->tag,
                       se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
@@ -2571,7 +2616,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
                prm->rq_result |= SS_RESIDUAL_UNDER;
        } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
                prm->residual = se_cmd->residual_count;
-               ql_dbg(ql_dbg_io, vha, 0x305d,
+               ql_dbg_qp(ql_dbg_io, qpair, 0x305d,
                    "Residual overflow: %d (tag %lld, op %x, bufflen %d, rq_result %x)\n",
                       prm->residual, se_cmd->tag, se_cmd->t_task_cdb ?
                       se_cmd->t_task_cdb[0] : 0, cmd->bufflen, prm->rq_result);
@@ -2585,7 +2630,7 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
                 */
                if (qlt_has_data(cmd)) {
                        if (QLA_TGT_SENSE_VALID(prm->sense_buffer) ||
-                           (IS_FWI2_CAPABLE(ha) &&
+                           (IS_FWI2_CAPABLE(cmd->vha->hw) &&
                            (prm->rq_result != 0))) {
                                prm->add_status_pkt = 1;
                                (*full_req_cnt)++;
@@ -2596,17 +2641,17 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
        return 0;
 }
 
-static inline int qlt_need_explicit_conf(struct qla_hw_data *ha,
-       struct qla_tgt_cmd *cmd, int sending_sense)
+static inline int qlt_need_explicit_conf(struct qla_tgt_cmd *cmd,
+    int sending_sense)
 {
-       if (ha->tgt.enable_class_2)
+       if (cmd->qpair->enable_class_2)
                return 0;
 
        if (sending_sense)
                return cmd->conf_compl_supported;
        else
-               return ha->tgt.enable_explicit_conf &&
-                   cmd->conf_compl_supported;
+               return cmd->qpair->enable_explicit_conf &&
+                    cmd->conf_compl_supported;
 }
 
 static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
@@ -2615,7 +2660,7 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
        prm->sense_buffer_len = min_t(uint32_t, prm->sense_buffer_len,
            (uint32_t)sizeof(ctio->u.status1.sense_data));
        ctio->u.status0.flags |= cpu_to_le16(CTIO7_FLAGS_SEND_STATUS);
-       if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 0)) {
+       if (qlt_need_explicit_conf(prm->cmd, 0)) {
                ctio->u.status0.flags |= cpu_to_le16(
                    CTIO7_FLAGS_EXPLICIT_CONFORM |
                    CTIO7_FLAGS_CONFORM_REQ);
@@ -2625,9 +2670,9 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
        if (QLA_TGT_SENSE_VALID(prm->sense_buffer)) {
                int i;
 
-               if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 1)) {
+               if (qlt_need_explicit_conf(prm->cmd, 1)) {
                        if ((prm->rq_result & SS_SCSI_STATUS_BYTE) != 0) {
-                               ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe017,
+                               ql_dbg_qp(ql_dbg_tgt, prm->cmd->qpair, 0xe017,
                                    "Skipping EXPLICIT_CONFORM and "
                                    "CTIO7_FLAGS_CONFORM_REQ for FCP READ w/ "
                                    "non GOOD status\n");
@@ -2795,7 +2840,7 @@ qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx,
 }
 
 static inline int
-qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
+qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
 {
        uint32_t                *cur_dsd;
        uint32_t                transfer_length = 0;
@@ -2814,16 +2859,17 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
        struct atio_from_isp *atio = &prm->cmd->atio;
        struct qla_tc_param     tc;
        uint16_t t16;
+       scsi_qla_host_t *vha = cmd->vha;
 
        ha = vha->hw;
 
-       pkt = (struct ctio_crc2_to_fw *)vha->req->ring_ptr;
+       pkt = (struct ctio_crc2_to_fw *)qpair->req->ring_ptr;
        prm->pkt = pkt;
        memset(pkt, 0, sizeof(*pkt));
 
-       ql_dbg(ql_dbg_tgt, vha, 0xe071,
+       ql_dbg_qp(ql_dbg_tgt, cmd->qpair, 0xe071,
                "qla_target(%d):%s: se_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n",
-               vha->vp_idx, __func__, se_cmd, se_cmd->prot_op,
+               cmd->vp_idx, __func__, se_cmd, se_cmd->prot_op,
                prm->prot_sg, prm->prot_seg_cnt, se_cmd->t_task_lba);
 
        if ((se_cmd->prot_op == TARGET_PROT_DIN_INSERT) ||
@@ -2886,9 +2932,9 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
        /* Update entry type to indicate Command Type CRC_2 IOCB */
        pkt->entry_type  = CTIO_CRC2;
        pkt->entry_count = 1;
-       pkt->vp_index = vha->vp_idx;
+       pkt->vp_index = cmd->vp_idx;
 
-       h = qlt_make_handle(vha);
+       h = qlt_make_handle(qpair);
        if (unlikely(h == QLA_TGT_NULL_HANDLE)) {
                /*
                 * CTIO type 7 from the firmware doesn't provide a way to
@@ -2897,9 +2943,10 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
                 */
                return -EAGAIN;
        } else
-               ha->tgt.cmds[h-1] = prm->cmd;
+               qpair->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
 
-       pkt->handle  = h | CTIO_COMPLETION_HANDLE_MARK;
+       pkt->handle  = MAKE_HANDLE(qpair->req->id, h);
+       pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
        pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
        pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
        pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
@@ -3003,7 +3050,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
 
 crc_queuing_error:
        /* Cleanup will be performed by the caller */
-       vha->hw->tgt.cmds[h - 1] = NULL;
+       qpair->req->outstanding_cmds[h] = NULL;
 
        return QLA_FUNCTION_FAILED;
 }
@@ -3016,33 +3063,28 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
        uint8_t scsi_status)
 {
        struct scsi_qla_host *vha = cmd->vha;
-       struct qla_hw_data *ha = vha->hw;
+       struct qla_qpair *qpair = cmd->qpair;
        struct ctio7_to_24xx *pkt;
        struct qla_tgt_prm prm;
        uint32_t full_req_cnt = 0;
        unsigned long flags = 0;
        int res;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
        if (cmd->sess && cmd->sess->deleted) {
                cmd->state = QLA_TGT_STATE_PROCESSED;
                if (cmd->sess->logout_completed)
                        /* no need to terminate. FW already freed exchange. */
                        qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
                else
-                       qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                       qlt_send_term_exchange(qpair, cmd, &cmd->atio, 0, 0);
                return 0;
        }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
-       memset(&prm, 0, sizeof(prm));
 
-       ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
-           "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n",
+       ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018,
+           "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p] qp %d\n",
            (xmit_type & QLA_TGT_XMIT_STATUS) ?
            1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction,
-           &cmd->se_cmd);
+           &cmd->se_cmd, qpair->id);
 
        res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
            &full_req_cnt);
@@ -3050,39 +3092,39 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
                return res;
        }
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
 
        if (xmit_type == QLA_TGT_XMIT_STATUS)
                vha->tgt_counters.core_qla_snd_status++;
        else
                vha->tgt_counters.core_qla_que_buf++;
 
-       if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) {
+       if (!qpair->fw_started || cmd->reset_count != qpair->chip_reset) {
                /*
                 * Either the port is not online or this request was from
                 * previous life, just abort the processing.
                 */
                cmd->state = QLA_TGT_STATE_PROCESSED;
                qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
-               ql_dbg(ql_dbg_async, vha, 0xe101,
+               ql_dbg_qp(ql_dbg_async, qpair, 0xe101,
                        "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
                        vha->flags.online, qla2x00_reset_active(vha),
-                       cmd->reset_count, ha->chip_reset);
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                       cmd->reset_count, qpair->chip_reset);
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
                return 0;
        }
 
        /* Does F/W have an IOCBs for this request */
-       res = qlt_check_reserve_free_req(vha, full_req_cnt);
+       res = qlt_check_reserve_free_req(qpair, full_req_cnt);
        if (unlikely(res))
                goto out_unmap_unlock;
 
        if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA))
-               res = qlt_build_ctio_crc2_pkt(&prm, vha);
+               res = qlt_build_ctio_crc2_pkt(qpair, &prm);
        else
-               res = qlt_24xx_build_ctio_pkt(&prm, vha);
+               res = qlt_24xx_build_ctio_pkt(qpair, &prm);
        if (unlikely(res != 0)) {
-               vha->req->cnt += full_req_cnt;
+               qpair->req->cnt += full_req_cnt;
                goto out_unmap_unlock;
        }
 
@@ -3104,7 +3146,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
                                    cpu_to_le32(prm.residual);
                                pkt->u.status0.flags |= cpu_to_le16(
                                    CTIO7_FLAGS_SEND_STATUS);
-                               if (qlt_need_explicit_conf(ha, cmd, 0)) {
+                               if (qlt_need_explicit_conf(cmd, 0)) {
                                        pkt->u.status0.flags |=
                                            cpu_to_le16(
                                                CTIO7_FLAGS_EXPLICIT_CONFORM |
@@ -3119,9 +3161,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
                         * req_pkt().
                         */
                        struct ctio7_to_24xx *ctio =
-                               (struct ctio7_to_24xx *)qlt_get_req_pkt(vha);
+                               (struct ctio7_to_24xx *)qlt_get_req_pkt(
+                                   qpair->req);
 
-                       ql_dbg(ql_dbg_io, vha, 0x305e,
+                       ql_dbg_qp(ql_dbg_tgt, qpair, 0x305e,
                            "Building additional status packet 0x%p.\n",
                            ctio);
 
@@ -3148,7 +3191,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
                         */
                        qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio,
                            &prm);
-                       pr_debug("Status CTIO7: %p\n", ctio);
                }
        } else
                qlt_24xx_init_ctio_to_isp(pkt, &prm);
@@ -3159,14 +3201,17 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return 0;
 
 out_unmap_unlock:
        qlt_unmap_sg(vha, cmd);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return res;
 }
@@ -3176,11 +3221,11 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 {
        struct ctio7_to_24xx *pkt;
        struct scsi_qla_host *vha = cmd->vha;
-       struct qla_hw_data *ha = vha->hw;
        struct qla_tgt *tgt = cmd->tgt;
        struct qla_tgt_prm prm;
-       unsigned long flags;
+       unsigned long flags = 0;
        int res = 0;
+       struct qla_qpair *qpair = cmd->qpair;
 
        memset(&prm, 0, sizeof(prm));
        prm.cmd = cmd;
@@ -3188,17 +3233,11 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
        prm.sg = NULL;
        prm.req_cnt = 1;
 
-       /* Send marker if required */
-       if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
-               return -EIO;
-
        /* Calculate number of entries and segments required */
        if (qlt_pci_map_calc_cnt(&prm) != 0)
                return -EAGAIN;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-
-       if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) ||
+       if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
            (cmd->sess && cmd->sess->deleted)) {
                /*
                 * Either the port is not online or this request was from
@@ -3206,25 +3245,25 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
                 */
                cmd->state = QLA_TGT_STATE_NEED_DATA;
                qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
-               ql_dbg(ql_dbg_async, vha, 0xe102,
+               ql_dbg_qp(ql_dbg_async, qpair, 0xe102,
                        "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
                        vha->flags.online, qla2x00_reset_active(vha),
-                       cmd->reset_count, ha->chip_reset);
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                       cmd->reset_count, qpair->chip_reset);
                return 0;
        }
 
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
        /* Does F/W have an IOCBs for this request */
-       res = qlt_check_reserve_free_req(vha, prm.req_cnt);
+       res = qlt_check_reserve_free_req(qpair, prm.req_cnt);
        if (res != 0)
                goto out_unlock_free_unmap;
        if (cmd->se_cmd.prot_op)
-               res = qlt_build_ctio_crc2_pkt(&prm, vha);
+               res = qlt_build_ctio_crc2_pkt(qpair, &prm);
        else
-               res = qlt_24xx_build_ctio_pkt(&prm, vha);
+               res = qlt_24xx_build_ctio_pkt(qpair, &prm);
 
        if (unlikely(res != 0)) {
-               vha->req->cnt += prm.req_cnt;
+               qpair->req->cnt += prm.req_cnt;
                goto out_unlock_free_unmap;
        }
 
@@ -3240,14 +3279,17 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return res;
 
 out_unlock_free_unmap:
        qlt_unmap_sg(vha, cmd);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return res;
 }
@@ -3258,7 +3300,7 @@ EXPORT_SYMBOL(qlt_rdy_to_xfer);
  * it is assumed either hardware_lock or qpair lock is held.
  */
 static void
-qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
+qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd,
        struct ctio_crc_from_fw *sts)
 {
        uint8_t         *ap = &sts->actual_dif[0];
@@ -3266,6 +3308,7 @@ qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
        uint64_t        lba = cmd->se_cmd.t_task_lba;
        uint8_t scsi_status, sense_key, asc, ascq;
        unsigned long flags;
+       struct scsi_qla_host *vha = cmd->vha;
 
        cmd->trc_flags |= TRC_DIF_ERR;
 
@@ -3284,15 +3327,12 @@ qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
 
        /* check appl tag */
        if (cmd->e_app_tag != cmd->a_app_tag) {
-               ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
-                       "App Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
-                       "Ref[%x|%x], App[%x|%x], "
-                       "Guard [%x|%x] cmd=%p ox_id[%04x]",
-                       cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
-                       cmd->a_ref_tag, cmd->e_ref_tag,
-                       cmd->a_app_tag, cmd->e_app_tag,
-                       cmd->a_guard, cmd->e_guard,
-                       cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+               ql_dbg(ql_dbg_tgt_dif, vha, 0xe00d,
+                   "App Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] Ref[%x|%x], App[%x|%x], Guard [%x|%x] cmd=%p ox_id[%04x]",
+                   cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+                   cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag,
+                   cmd->e_app_tag, cmd->a_guard, cmd->e_guard, cmd,
+                   cmd->atio.u.isp24.fcp_hdr.ox_id);
 
                cmd->dif_err_code = DIF_ERR_APP;
                scsi_status = SAM_STAT_CHECK_CONDITION;
@@ -3303,15 +3343,12 @@ qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
 
        /* check ref tag */
        if (cmd->e_ref_tag != cmd->a_ref_tag) {
-               ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
-                       "Ref Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
-                       "Ref[%x|%x], App[%x|%x], "
-                       "Guard[%x|%x] cmd=%p ox_id[%04x] ",
-                       cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
-                       cmd->a_ref_tag, cmd->e_ref_tag,
-                       cmd->a_app_tag, cmd->e_app_tag,
-                       cmd->a_guard, cmd->e_guard,
-                       cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+               ql_dbg(ql_dbg_tgt_dif, vha, 0xe00e,
+                   "Ref Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] Ref[%x|%x], App[%x|%x], Guard[%x|%x] cmd=%p ox_id[%04x] ",
+                   cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+                   cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag,
+                   cmd->e_app_tag, cmd->a_guard, cmd->e_guard, cmd,
+                   cmd->atio.u.isp24.fcp_hdr.ox_id);
 
                cmd->dif_err_code = DIF_ERR_REF;
                scsi_status = SAM_STAT_CHECK_CONDITION;
@@ -3323,15 +3360,13 @@ qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
 
        /* check guard */
        if (cmd->e_guard != cmd->a_guard) {
-               ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
-                       "Guard ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] "
-                       "Ref[%x|%x], App[%x|%x], "
-                       "Guard [%x|%x] cmd=%p ox_id[%04x]",
-                       cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
-                       cmd->a_ref_tag, cmd->e_ref_tag,
-                       cmd->a_app_tag, cmd->e_app_tag,
-                       cmd->a_guard, cmd->e_guard,
-                       cmd, cmd->atio.u.isp24.fcp_hdr.ox_id);
+               ql_dbg(ql_dbg_tgt_dif, vha, 0xe012,
+                   "Guard ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] Ref[%x|%x], App[%x|%x], Guard [%x|%x] cmd=%p ox_id[%04x]",
+                   cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks,
+                   cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag,
+                   cmd->e_app_tag, cmd->a_guard, cmd->e_guard, cmd,
+                   cmd->atio.u.isp24.fcp_hdr.ox_id);
+
                cmd->dif_err_code = DIF_ERR_GRD;
                scsi_status = SAM_STAT_CHECK_CONDITION;
                sense_key = ABORTED_COMMAND;
@@ -3354,7 +3389,8 @@ out:
                }
                spin_unlock_irqrestore(&cmd->cmd_lock, flags);
 
-               qlt_send_resp_ctio(vha, cmd, scsi_status, sense_key, asc, ascq);
+               qlt_send_resp_ctio(qpair, cmd, scsi_status, sense_key, asc,
+                   ascq);
                /* assume scsi status gets out on the wire.
                 * Will not wait for completion.
                 */
@@ -3420,9 +3456,6 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
        unsigned long flags = 0;
        int rc;
 
-       if (qlt_issue_marker(vha, ha_locked) < 0)
-               return;
-
        if (ha_locked) {
                rc = __qlt_send_term_imm_notif(vha, imm);
 
@@ -3449,21 +3482,24 @@ done:
                spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
 }
 
-/* If hardware_lock held on entry, might drop it, then reaquire */
-/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
-static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
+/*
+ * If hardware_lock held on entry, might drop it, then reaquire
+ * This function sends the appropriate CTIO to ISP 2xxx or 24xx
+ */
+static int __qlt_send_term_exchange(struct qla_qpair *qpair,
        struct qla_tgt_cmd *cmd,
        struct atio_from_isp *atio)
 {
+       struct scsi_qla_host *vha = qpair->vha;
        struct ctio7_to_24xx *ctio24;
        struct qla_hw_data *ha = vha->hw;
        request_t *pkt;
        int ret = 0;
        uint16_t temp;
 
-       ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha);
+       ql_dbg(ql_dbg_tgt, vha, 0xe009, "Sending TERM EXCH CTIO (ha=%p)\n", ha);
 
-       pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
+       pkt = (request_t *)qla2x00_alloc_iocbs_ready(qpair, NULL);
        if (pkt == NULL) {
                ql_dbg(ql_dbg_tgt, vha, 0xe050,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -3494,9 +3530,9 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
        ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
        ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
        ctio24->exchange_addr = atio->u.isp24.exchange_addr;
-       ctio24->u.status1.flags = (atio->u.isp24.attr << 9) |
-           cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
-               CTIO7_FLAGS_TERMINATE);
+       temp = (atio->u.isp24.attr << 9) | CTIO7_FLAGS_STATUS_MODE_1 |
+               CTIO7_FLAGS_TERMINATE;
+       ctio24->u.status1.flags = cpu_to_le16(temp);
        temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
        ctio24->u.status1.ox_id = cpu_to_le16(temp);
 
@@ -3509,28 +3545,35 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
 
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
        return ret;
 }
 
-static void qlt_send_term_exchange(struct scsi_qla_host *vha,
+static void qlt_send_term_exchange(struct qla_qpair *qpair,
        struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked,
        int ul_abort)
 {
+       struct scsi_qla_host *vha;
        unsigned long flags = 0;
        int rc;
 
-       if (qlt_issue_marker(vha, ha_locked) < 0)
-               return;
+       /* why use different vha? NPIV */
+       if (cmd)
+               vha = cmd->vha;
+       else
+               vha = qpair->vha;
 
        if (ha_locked) {
-               rc = __qlt_send_term_exchange(vha, cmd, atio);
+               rc = __qlt_send_term_exchange(qpair, cmd, atio);
                if (rc == -ENOMEM)
                        qlt_alloc_qfull_cmd(vha, atio, 0, 0);
                goto done;
        }
-       spin_lock_irqsave(&vha->hw->hardware_lock, flags);
-       rc = __qlt_send_term_exchange(vha, cmd, atio);
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       rc = __qlt_send_term_exchange(qpair, cmd, atio);
        if (rc == -ENOMEM)
                qlt_alloc_qfull_cmd(vha, atio, 0, 0);
 
@@ -3542,7 +3585,7 @@ done:
        }
 
        if (!ha_locked)
-               spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        return;
 }
@@ -3614,17 +3657,17 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
                 *  1) XFER Rdy completion + CMD_T_ABORT
                 *  2) TCM TMR - drain_state_list
                 */
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
-                       "multiple abort. %p transport_state %x, t_state %x,"
-                       " se_cmd_flags %x \n", cmd, cmd->se_cmd.transport_state,
-                       cmd->se_cmd.t_state,cmd->se_cmd.se_cmd_flags);
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf016,
+                   "multiple abort. %p transport_state %x, t_state %x, "
+                   "se_cmd_flags %x\n", cmd, cmd->se_cmd.transport_state,
+                   cmd->se_cmd.t_state, cmd->se_cmd.se_cmd_flags);
                return EIO;
        }
        cmd->aborted = 1;
        cmd->trc_flags |= TRC_ABORT;
        spin_unlock_irqrestore(&cmd->cmd_lock, flags);
 
-       qlt_send_term_exchange(vha, cmd, &cmd->atio, 0, 1);
+       qlt_send_term_exchange(cmd->qpair, cmd, &cmd->atio, 0, 1);
        return 0;
 }
 EXPORT_SYMBOL(qlt_abort_cmd);
@@ -3663,13 +3706,14 @@ EXPORT_SYMBOL(qlt_free_cmd);
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
+static int qlt_term_ctio_exchange(struct qla_qpair *qpair, void *ctio,
        struct qla_tgt_cmd *cmd, uint32_t status)
 {
        int term = 0;
+       struct scsi_qla_host *vha = qpair->vha;
 
        if (cmd->se_cmd.prot_op)
-               ql_dbg(ql_dbg_tgt_dif, vha, 0xffff,
+               ql_dbg(ql_dbg_tgt_dif, vha, 0xe013,
                    "Term DIF cmd: lba[0x%llx|%lld] len[0x%x] "
                    "se_cmd=%p tag[%x] op %#x/%s",
                     cmd->lba, cmd->lba,
@@ -3686,55 +3730,53 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
                term = 1;
 
        if (term)
-               qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
+               qlt_term_ctio_exchange(qpair, ctio, cmd, status);
 
        return term;
 }
 
-/* ha->hardware_lock supposed to be held on entry */
-static inline struct qla_tgt_cmd *qlt_get_cmd(struct scsi_qla_host *vha,
-       uint32_t handle)
-{
-       struct qla_hw_data *ha = vha->hw;
-
-       handle--;
-       if (ha->tgt.cmds[handle] != NULL) {
-               struct qla_tgt_cmd *cmd = ha->tgt.cmds[handle];
-               ha->tgt.cmds[handle] = NULL;
-               return cmd;
-       } else
-               return NULL;
-}
 
 /* ha->hardware_lock supposed to be held on entry */
 static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
-       uint32_t handle, void *ctio)
+       struct rsp_que *rsp, uint32_t handle, void *ctio)
 {
        struct qla_tgt_cmd *cmd = NULL;
+       struct req_que *req;
+       int qid = GET_QID(handle);
+       uint32_t h = handle & ~QLA_TGT_HANDLE_MASK;
 
-       /* Clear out internal marks */
-       handle &= ~(CTIO_COMPLETION_HANDLE_MARK |
-           CTIO_INTERMEDIATE_HANDLE_MARK);
+       if (unlikely(h == QLA_TGT_SKIP_HANDLE))
+               return NULL;
 
-       if (handle != QLA_TGT_NULL_HANDLE) {
-               if (unlikely(handle == QLA_TGT_SKIP_HANDLE))
-                       return NULL;
+       if (qid == rsp->req->id) {
+               req = rsp->req;
+       } else if (vha->hw->req_q_map[qid]) {
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0x1000a,
+                   "qla_target(%d): CTIO completion with different QID %d handle %x\n",
+                   vha->vp_idx, rsp->id, handle);
+               req = vha->hw->req_q_map[qid];
+       } else {
+               return NULL;
+       }
+
+       h &= QLA_CMD_HANDLE_MASK;
 
-               /* handle-1 is actually used */
-               if (unlikely(handle > DEFAULT_OUTSTANDING_COMMANDS)) {
+       if (h != QLA_TGT_NULL_HANDLE) {
+               if (unlikely(h > req->num_outstanding_cmds)) {
                        ql_dbg(ql_dbg_tgt, vha, 0xe052,
                            "qla_target(%d): Wrong handle %x received\n",
                            vha->vp_idx, handle);
                        return NULL;
                }
-               cmd = qlt_get_cmd(vha, handle);
+
+               cmd = (struct qla_tgt_cmd *)req->outstanding_cmds[h];
                if (unlikely(cmd == NULL)) {
-                       ql_dbg(ql_dbg_tgt, vha, 0xe053,
-                           "qla_target(%d): Suspicious: unable to "
-                           "find the command with handle %x\n", vha->vp_idx,
-                           handle);
+                       ql_dbg(ql_dbg_async, vha, 0xe053,
+                           "qla_target(%d): Suspicious: unable to find the command with handle %x req->id %d rsp->id %d\n",
+                               vha->vp_idx, handle, req->id, rsp->id);
                        return NULL;
                }
+               req->outstanding_cmds[h] = NULL;
        } else if (ctio != NULL) {
                /* We can't get loop ID from CTIO7 */
                ql_dbg(ql_dbg_tgt, vha, 0xe054,
@@ -3747,33 +3789,30 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
 }
 
 /* hardware_lock should be held by caller. */
-static void
+void
 qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
 {
        struct qla_hw_data *ha = vha->hw;
-       uint32_t handle;
 
        if (cmd->sg_mapped)
                qlt_unmap_sg(vha, cmd);
 
-       handle = qlt_make_handle(vha);
-
        /* TODO: fix debug message type and ids. */
        if (cmd->state == QLA_TGT_STATE_PROCESSED) {
                ql_dbg(ql_dbg_io, vha, 0xff00,
-                   "HOST-ABORT: handle=%d, state=PROCESSED.\n", handle);
+                   "HOST-ABORT: state=PROCESSED.\n");
        } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
                cmd->write_data_transferred = 0;
                cmd->state = QLA_TGT_STATE_DATA_IN;
 
                ql_dbg(ql_dbg_io, vha, 0xff01,
-                   "HOST-ABORT: handle=%d, state=DATA_IN.\n", handle);
+                   "HOST-ABORT: state=DATA_IN.\n");
 
                ha->tgt.tgt_ops->handle_data(cmd);
                return;
        } else {
                ql_dbg(ql_dbg_io, vha, 0xff03,
-                   "HOST-ABORT: handle=%d, state=BAD(%d).\n", handle,
+                   "HOST-ABORT: state=BAD(%d).\n",
                    cmd->state);
                dump_stack();
        }
@@ -3782,51 +3821,16 @@ qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd)
        ha->tgt.tgt_ops->free_cmd(cmd);
 }
 
-void
-qlt_host_reset_handler(struct qla_hw_data *ha)
-{
-       struct qla_tgt_cmd *cmd;
-       unsigned long flags;
-       scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
-       scsi_qla_host_t *vha = NULL;
-       struct qla_tgt *tgt = base_vha->vha_tgt.qla_tgt;
-       uint32_t i;
-
-       if (!base_vha->hw->tgt.tgt_ops)
-               return;
-
-       if (!tgt || qla_ini_mode_enabled(base_vha)) {
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003,
-                       "Target mode disabled\n");
-               return;
-       }
-
-       ql_dbg(ql_dbg_tgt_mgt, vha, 0xff10,
-           "HOST-ABORT-HNDLR: base_vha->dpc_flags=%lx.\n",
-           base_vha->dpc_flags);
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       for (i = 1; i < DEFAULT_OUTSTANDING_COMMANDS + 1; i++) {
-               cmd = qlt_get_cmd(base_vha, i);
-               if (!cmd)
-                       continue;
-               /* ha->tgt.cmds entry is cleared by qlt_get_cmd. */
-               vha = cmd->vha;
-               qlt_abort_cmd_on_host_reset(vha, cmd);
-       }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  */
-static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
-       uint32_t status, void *ctio)
+static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
+    struct rsp_que *rsp, uint32_t handle, uint32_t status, void *ctio)
 {
        struct qla_hw_data *ha = vha->hw;
        struct se_cmd *se_cmd;
        struct qla_tgt_cmd *cmd;
+       struct qla_qpair *qpair = rsp->qpair;
 
        if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) {
                /* That could happen only in case of an error/reset/abort */
@@ -3838,7 +3842,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
                return;
        }
 
-       cmd = qlt_ctio_to_cmd(vha, handle, ctio);
+       cmd = qlt_ctio_to_cmd(vha, rsp, handle, ctio);
        if (cmd == NULL)
                return;
 
@@ -3883,7 +3887,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
                                 */
                                cmd->sess->logout_on_delete = 0;
                                cmd->sess->send_els_logo = 1;
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
+                               ql_dbg(ql_dbg_disc, vha, 0x20f8,
                                    "%s %d %8phC post del sess\n",
                                    __func__, __LINE__, cmd->sess->port_name);
 
@@ -3902,7 +3906,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
                            *((u64 *)&crc->actual_dif[0]),
                            *((u64 *)&crc->expected_dif[0]));
 
-                       qlt_handle_dif_error(vha, cmd, ctio);
+                       qlt_handle_dif_error(qpair, cmd, ctio);
                        return;
                }
                default:
@@ -3922,7 +3926,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
                if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
                    (!cmd->aborted)) {
                        cmd->trc_flags |= TRC_CTIO_ERR;
-                       if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
+                       if (qlt_term_ctio_exchange(qpair, ctio, cmd, status))
                                return;
                }
        }
@@ -3998,18 +4002,16 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
 {
        scsi_qla_host_t *vha = cmd->vha;
        struct qla_hw_data *ha = vha->hw;
-       struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        struct fc_port *sess = cmd->sess;
        struct atio_from_isp *atio = &cmd->atio;
        unsigned char *cdb;
        unsigned long flags;
        uint32_t data_length;
        int ret, fcp_task_attr, data_dir, bidi = 0;
+       struct qla_qpair *qpair = cmd->qpair;
 
        cmd->cmd_in_wq = 0;
        cmd->trc_flags |= TRC_DO_WORK;
-       if (tgt->tgt_stop)
-               goto out_term;
 
        if (cmd->aborted) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf082,
@@ -4021,8 +4023,6 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
        spin_lock_init(&cmd->cmd_lock);
        cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
        cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
-       cmd->unpacked_lun = scsilun_to_int(
-           (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun);
 
        if (atio->u.isp24.fcp_cmnd.rddata &&
            atio->u.isp24.fcp_cmnd.wrdata) {
@@ -4060,12 +4060,12 @@ out_term:
         * argument to qlt_send_term_exchange() and free the memory here.
         */
        cmd->trc_flags |= TRC_DO_WORK_ERR;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       qlt_send_term_exchange(vha, NULL, &cmd->atio, 1, 0);
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1, 0);
 
        qlt_decr_num_pend_cmds(vha);
        percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        ha->tgt.tgt_ops->put_sess(sess);
@@ -4085,6 +4085,110 @@ static void qlt_do_work(struct work_struct *work)
        __qlt_do_work(cmd);
 }
 
+void qlt_clr_qp_table(struct scsi_qla_host *vha)
+{
+       unsigned long flags;
+       struct qla_hw_data *ha = vha->hw;
+       struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+       void *node;
+       u64 key = 0;
+
+       ql_log(ql_log_info, vha, 0x706c,
+           "User update Number of Active Qpairs %d\n",
+           ha->tgt.num_act_qpairs);
+
+       spin_lock_irqsave(&ha->tgt.atio_lock, flags);
+
+       btree_for_each_safe64(&tgt->lun_qpair_map, key, node)
+               btree_remove64(&tgt->lun_qpair_map, key);
+
+       ha->base_qpair->lun_cnt = 0;
+       for (key = 0; key < ha->max_qpairs; key++)
+               if (ha->queue_pair_map[key])
+                       ha->queue_pair_map[key]->lun_cnt = 0;
+
+       spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
+}
+
+static void qlt_assign_qpair(struct scsi_qla_host *vha,
+       struct qla_tgt_cmd *cmd)
+{
+       struct qla_qpair *qpair, *qp;
+       struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+       struct qla_qpair_hint *h;
+
+       if (vha->flags.qpairs_available) {
+               h = btree_lookup64(&tgt->lun_qpair_map, cmd->unpacked_lun);
+               if (unlikely(!h)) {
+                       /* spread lun to qpair ratio evently */
+                       int lcnt = 0, rc;
+                       struct scsi_qla_host *base_vha =
+                               pci_get_drvdata(vha->hw->pdev);
+
+                       qpair = vha->hw->base_qpair;
+                       if (qpair->lun_cnt == 0) {
+                               qpair->lun_cnt++;
+                               h = qla_qpair_to_hint(tgt, qpair);
+                               BUG_ON(!h);
+                               rc = btree_insert64(&tgt->lun_qpair_map,
+                                       cmd->unpacked_lun, h, GFP_ATOMIC);
+                               if (rc) {
+                                       qpair->lun_cnt--;
+                                       ql_log(ql_log_info, vha, 0xd037,
+                                           "Unable to insert lun %llx into lun_qpair_map\n",
+                                           cmd->unpacked_lun);
+                               }
+                               goto out;
+                       } else {
+                               lcnt = qpair->lun_cnt;
+                       }
+
+                       h = NULL;
+                       list_for_each_entry(qp, &base_vha->qp_list,
+                           qp_list_elem) {
+                               if (qp->lun_cnt == 0) {
+                                       qp->lun_cnt++;
+                                       h = qla_qpair_to_hint(tgt, qp);
+                                       BUG_ON(!h);
+                                       rc = btree_insert64(&tgt->lun_qpair_map,
+                                           cmd->unpacked_lun, h, GFP_ATOMIC);
+                                       if (rc) {
+                                               qp->lun_cnt--;
+                                               ql_log(ql_log_info, vha, 0xd038,
+                                                       "Unable to insert lun %llx into lun_qpair_map\n",
+                                                       cmd->unpacked_lun);
+                                       }
+                                       qpair = qp;
+                                       goto out;
+                               } else {
+                                       if (qp->lun_cnt < lcnt) {
+                                               lcnt = qp->lun_cnt;
+                                               qpair = qp;
+                                               continue;
+                                       }
+                               }
+                       }
+                       BUG_ON(!qpair);
+                       qpair->lun_cnt++;
+                       h = qla_qpair_to_hint(tgt, qpair);
+                       BUG_ON(!h);
+                       rc = btree_insert64(&tgt->lun_qpair_map,
+                               cmd->unpacked_lun, h, GFP_ATOMIC);
+                       if (rc) {
+                               qpair->lun_cnt--;
+                               ql_log(ql_log_info, vha, 0xd039,
+                                  "Unable to insert lun %llx into lun_qpair_map\n",
+                                  cmd->unpacked_lun);
+                       }
+               }
+       } else {
+               h = &tgt->qphints[0];
+       }
+out:
+       cmd->qpair = h->qpair;
+       cmd->se_cmd.cpuid = h->cpuid;
+}
+
 static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
                                       struct fc_port *sess,
                                       struct atio_from_isp *atio)
@@ -4099,7 +4203,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
 
        cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
        memset(cmd, 0, sizeof(struct qla_tgt_cmd));
-
+       cmd->cmd_type = TYPE_TGT_CMD;
        memcpy(&cmd->atio, atio, sizeof(*atio));
        cmd->state = QLA_TGT_STATE_NEW;
        cmd->tgt = vha->vha_tgt.qla_tgt;
@@ -4113,14 +4217,15 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
        cmd->trc_flags = 0;
        cmd->jiffies_at_alloc = get_jiffies_64();
 
-       cmd->reset_count = vha->hw->chip_reset;
+       cmd->unpacked_lun = scsilun_to_int(
+           (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun);
+       qlt_assign_qpair(vha, cmd);
+       cmd->reset_count = vha->hw->base_qpair->chip_reset;
+       cmd->vp_idx = vha->vp_idx;
 
        return cmd;
 }
 
-static void qlt_send_busy(struct scsi_qla_host *, struct atio_from_isp *,
-                         uint16_t);
-
 static void qlt_create_sess_from_atio(struct work_struct *work)
 {
        struct qla_tgt_sess_op *op = container_of(work,
@@ -4166,10 +4271,15 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
         */
        cmd = qlt_get_tag(vha, sess, &op->atio);
        if (!cmd) {
-               spin_lock_irqsave(&ha->hardware_lock, flags);
-               qlt_send_busy(vha, &op->atio, SAM_STAT_BUSY);
+               struct qla_qpair *qpair = ha->base_qpair;
+
+               spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+               qlt_send_busy(qpair, &op->atio, SAM_STAT_BUSY);
+               spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
+               spin_lock_irqsave(&ha->tgt.sess_lock, flags);
                ha->tgt.tgt_ops->put_sess(sess);
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
                kfree(op);
                return;
        }
@@ -4182,9 +4292,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
        kfree(op);
        return;
 out_term:
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       qlt_send_term_exchange(vha, NULL, &op->atio, 1, 0);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       qlt_send_term_exchange(vha->hw->base_qpair, NULL, &op->atio, 0, 0);
        kfree(op);
 }
 
@@ -4214,9 +4322,9 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
                memcpy(&op->atio, atio, sizeof(*atio));
                op->vha = vha;
 
-               spin_lock(&vha->cmd_list_lock);
+               spin_lock_irqsave(&vha->cmd_list_lock, flags);
                list_add_tail(&op->cmd_list, &vha->qla_sess_op_cmd_list);
-               spin_unlock(&vha->cmd_list_lock);
+               spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 
                INIT_WORK(&op->work, qlt_create_sess_from_atio);
                queue_work(qla_tgt_wq, &op->work);
@@ -4226,7 +4334,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
        /* Another WWN used to have our s_id. Our PLOGI scheduled its
         * session deletion, but it's still in sess_del_work wq */
        if (sess->deleted) {
-               ql_dbg(ql_dbg_io, vha, 0x3061,
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002,
                    "New command while old session %p is being deleted\n",
                    sess);
                return -EFAULT;
@@ -4236,7 +4344,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
         * Do kref_get() before returning + dropping qla_hw_data->hardware_lock.
         */
        if (!kref_get_unless_zero(&sess->sess_kref)) {
-               ql_dbg(ql_dbg_tgt, vha, 0xffff,
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004,
                    "%s: kref_get fail, %8phC oxid %x \n",
                    __func__, sess->port_name,
                     be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id));
@@ -4255,15 +4363,15 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
 
        cmd->cmd_in_wq = 1;
        cmd->trc_flags |= TRC_NEW_CMD;
-       cmd->se_cmd.cpuid = ha->msix_count ?
-               ha->tgt.rspq_vector_cpuid : WORK_CPU_UNBOUND;
 
        spin_lock_irqsave(&vha->cmd_list_lock, flags);
        list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
        spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 
        INIT_WORK(&cmd->work, qlt_do_work);
-       if (ha->msix_count) {
+       if (vha->flags.qpairs_available) {
+               queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work);
+       } else if (ha->msix_count) {
                if (cmd->atio.u.isp24.fcp_cmnd.rddata)
                        queue_work_on(smp_processor_id(), qla_tgt_wq,
                            &cmd->work);
@@ -4273,8 +4381,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
        } else {
                queue_work(qla_tgt_wq, &cmd->work);
        }
-       return 0;
 
+       return 0;
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4304,7 +4412,8 @@ static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun,
        }
        mcmd->tmr_func = fn;
        mcmd->flags = flags;
-       mcmd->reset_count = vha->hw->chip_reset;
+       mcmd->reset_count = ha->base_qpair->chip_reset;
+       mcmd->qpair = ha->base_qpair;
 
        switch (fn) {
        case QLA_TGT_LUN_RESET:
@@ -4331,13 +4440,12 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt *tgt;
        struct fc_port *sess;
-       uint32_t lun, unpacked_lun;
+       u64 unpacked_lun;
        int fn;
        unsigned long flags;
 
        tgt = vha->vha_tgt.qla_tgt;
 
-       lun = a->u.isp24.fcp_cmnd.lun;
        fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
 
        spin_lock_irqsave(&ha->tgt.sess_lock, flags);
@@ -4345,7 +4453,8 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
            a->u.isp24.fcp_hdr.s_id);
        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
-       unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
+       unpacked_lun =
+           scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
 
        if (!sess) {
                ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024,
@@ -4368,7 +4477,7 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
        struct atio_from_isp *a = (struct atio_from_isp *)iocb;
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt_mgmt_cmd *mcmd;
-       uint32_t lun, unpacked_lun;
+       u64 unpacked_lun;
        int rc;
 
        mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC);
@@ -4384,10 +4493,11 @@ static int __qlt_abort_task(struct scsi_qla_host *vha,
        memcpy(&mcmd->orig_iocb.imm_ntfy, iocb,
            sizeof(mcmd->orig_iocb.imm_ntfy));
 
-       lun = a->u.isp24.fcp_cmnd.lun;
-       unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
-       mcmd->reset_count = vha->hw->chip_reset;
+       unpacked_lun =
+           scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
+       mcmd->reset_count = ha->base_qpair->chip_reset;
        mcmd->tmr_func = QLA_TGT_2G_ABORT_TASK;
+       mcmd->qpair = ha->base_qpair;
 
        rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, mcmd->tmr_func,
            le16_to_cpu(iocb->u.isp2x.seq_id));
@@ -4491,7 +4601,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
                                 * Another wwn used to have our s_id/loop_id
                                 * kill the session, but don't free the loop_id
                                 */
-                               ql_dbg(ql_dbg_tgt_tmr, vha, 0xffff,
+                               ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b,
                                    "Invalidating sess %p loop_id %d wwn %llx.\n",
                                    other_sess, other_sess->loop_id, other_wwn);
 
@@ -4527,12 +4637,13 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id)
        struct qla_tgt_cmd *cmd;
        uint32_t key;
        int count = 0;
+       unsigned long flags;
 
        key = (((u32)s_id->b.domain << 16) |
               ((u32)s_id->b.area   <<  8) |
               ((u32)s_id->b.al_pa));
 
-       spin_lock(&vha->cmd_list_lock);
+       spin_lock_irqsave(&vha->cmd_list_lock, flags);
        list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
                uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
 
@@ -4557,7 +4668,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id)
                        count++;
                }
        }
-       spin_unlock(&vha->cmd_list_lock);
+       spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 
        return count;
 }
@@ -4670,9 +4781,9 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
                        sess->keep_nport_handle = ((sess->loop_id == loop_id) &&
                           (sess->d_id.b24 == port_id.b24));
 
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
-                                  "%s %d %8phC post del sess\n",
-                                  __func__, __LINE__, sess->port_name);
+                       ql_dbg(ql_dbg_disc, vha, 0x20f9,
+                           "%s %d %8phC post del sess\n",
+                           __func__, __LINE__, sess->port_name);
 
 
                        qlt_schedule_sess_for_deletion_lock(sess);
@@ -4742,7 +4853,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
                /* Make session global (not used in fabric mode) */
                if (ha->current_topology != ISP_CFG_F) {
                        if (sess) {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
+                               ql_dbg(ql_dbg_disc, vha, 0x20fa,
                                    "%s %d %8phC post nack\n",
                                    __func__, __LINE__, sess->port_name);
                                qla24xx_post_nack_work(vha, sess, iocb,
@@ -4755,7 +4866,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
                        }
                } else {
                        if (sess) {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
+                               ql_dbg(ql_dbg_disc, vha, 0x20fb,
                                    "%s %d %8phC post nack\n",
                                    __func__, __LINE__, sess->port_name);
                                qla24xx_post_nack_work(vha, sess, iocb,
@@ -4789,7 +4900,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 
                res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS);
 
-               ql_dbg(ql_dbg_disc, vha, 0xffff,
+               ql_dbg(ql_dbg_disc, vha, 0x20fc,
                    "%s: logo %llx res %d sess %p ",
                    __func__, wwn, res, sess);
                if (res == 0) {
@@ -4813,15 +4924,15 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
        {
                struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
                if (tgt->link_reinit_iocb_pending) {
-                       qlt_send_notify_ack(vha, &tgt->link_reinit_iocb,
-                           0, 0, 0, 0, 0, 0);
+                       qlt_send_notify_ack(ha->base_qpair,
+                           &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0);
                        tgt->link_reinit_iocb_pending = 0;
                }
 
                sess = qla2x00_find_fcport_by_wwpn(vha,
                    iocb->u.isp24.port_name, 1);
                if (sess) {
-                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                       ql_dbg(ql_dbg_disc, vha, 0x20fd,
                                "sess %p lid %d|%d DS %d LS %d\n",
                                sess, sess->loop_id, loop_id,
                                sess->disc_state, sess->fw_login_state);
@@ -4877,8 +4988,8 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
                    le16_to_cpu(iocb->u.isp24.nport_handle),
                    iocb->u.isp24.status_subcode);
                if (tgt->link_reinit_iocb_pending) {
-                       qlt_send_notify_ack(vha, &tgt->link_reinit_iocb,
-                           0, 0, 0, 0, 0, 0);
+                       qlt_send_notify_ack(ha->base_qpair,
+                           &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0);
                }
                memcpy(&tgt->link_reinit_iocb, iocb, sizeof(*iocb));
                tgt->link_reinit_iocb_pending = 1;
@@ -4972,33 +5083,36 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
        }
 
        if (send_notify_ack)
-               qlt_send_notify_ack(vha, iocb, add_flags, 0, 0, 0, 0, 0);
+               qlt_send_notify_ack(ha->base_qpair, iocb, add_flags, 0, 0, 0,
+                   0, 0);
 }
 
 /*
  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
  * This function sends busy to ISP 2xxx or 24xx.
  */
-static int __qlt_send_busy(struct scsi_qla_host *vha,
+static int __qlt_send_busy(struct qla_qpair *qpair,
        struct atio_from_isp *atio, uint16_t status)
 {
+       struct scsi_qla_host *vha = qpair->vha;
        struct ctio7_to_24xx *ctio24;
        struct qla_hw_data *ha = vha->hw;
        request_t *pkt;
        struct fc_port *sess = NULL;
        unsigned long flags;
+       u16 temp;
 
        spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
            atio->u.isp24.fcp_hdr.s_id);
        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        if (!sess) {
-               qlt_send_term_exchange(vha, NULL, atio, 1, 0);
+               qlt_send_term_exchange(qpair, NULL, atio, 1, 0);
                return 0;
        }
        /* Sending marker isn't necessary, since we called from ISR */
 
-       pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL);
+       pkt = (request_t *)__qla2x00_alloc_iocbs(qpair, NULL);
        if (!pkt) {
                ql_dbg(ql_dbg_io, vha, 0x3063,
                    "qla_target(%d): %s failed: unable to allocate "
@@ -5019,10 +5133,10 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
        ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
        ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
        ctio24->exchange_addr = atio->u.isp24.exchange_addr;
-       ctio24->u.status1.flags = (atio->u.isp24.attr << 9) |
-           cpu_to_le16(
+       temp = (atio->u.isp24.attr << 9) |
                CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS |
-               CTIO7_FLAGS_DONT_RET_CTIO);
+               CTIO7_FLAGS_DONT_RET_CTIO;
+       ctio24->u.status1.flags = cpu_to_le16(temp);
        /*
         * CTIO from fw w/o se_cmd doesn't provide enough info to retry it,
         * if the explicit conformation is used.
@@ -5031,7 +5145,10 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
        ctio24->u.status1.scsi_status = cpu_to_le16(status);
        /* Memory Barrier */
        wmb();
-       qla2x00_start_iocbs(vha, vha->req);
+       if (qpair->reqq_start_iocbs)
+               qpair->reqq_start_iocbs(qpair);
+       else
+               qla2x00_start_iocbs(vha, qpair->req);
        return 0;
 }
 
@@ -5050,6 +5167,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
        struct se_session *se_sess;
        struct qla_tgt_cmd *cmd;
        int tag;
+       unsigned long flags;
 
        if (unlikely(tgt->tgt_stop)) {
                ql_dbg(ql_dbg_io, vha, 0x300a,
@@ -5108,8 +5226,9 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
 
        cmd->tgt = vha->vha_tgt.qla_tgt;
        cmd->vha = vha;
-       cmd->reset_count = vha->hw->chip_reset;
+       cmd->reset_count = ha->base_qpair->chip_reset;
        cmd->q_full = 1;
+       cmd->qpair = ha->base_qpair;
 
        if (qfull) {
                cmd->q_full = 1;
@@ -5118,6 +5237,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
        } else
                cmd->term_exchg = 1;
 
+       spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
        list_add_tail(&cmd->cmd_list, &vha->hw->tgt.q_full_list);
 
        vha->hw->tgt.num_qfull_cmds_alloc++;
@@ -5125,35 +5245,41 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
                vha->qla_stats.stat_max_qfull_cmds_alloc)
                vha->qla_stats.stat_max_qfull_cmds_alloc =
                        vha->hw->tgt.num_qfull_cmds_alloc;
+       spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
 }
 
 int
-qlt_free_qfull_cmds(struct scsi_qla_host *vha)
+qlt_free_qfull_cmds(struct qla_qpair *qpair)
 {
+       struct scsi_qla_host *vha = qpair->vha;
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags;
        struct qla_tgt_cmd *cmd, *tcmd;
-       struct list_head free_list;
+       struct list_head free_list, q_full_list;
        int rc = 0;
 
        if (list_empty(&ha->tgt.q_full_list))
                return 0;
 
        INIT_LIST_HEAD(&free_list);
+       INIT_LIST_HEAD(&q_full_list);
 
-       spin_lock_irqsave(&vha->hw->hardware_lock, flags);
-
+       spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
        if (list_empty(&ha->tgt.q_full_list)) {
-               spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+               spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
                return 0;
        }
 
-       list_for_each_entry_safe(cmd, tcmd, &ha->tgt.q_full_list, cmd_list) {
+       list_splice_init(&vha->hw->tgt.q_full_list, &q_full_list);
+       spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
+
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       list_for_each_entry_safe(cmd, tcmd, &q_full_list, cmd_list) {
                if (cmd->q_full)
                        /* cmd->state is a borrowed field to hold status */
-                       rc = __qlt_send_busy(vha, &cmd->atio, cmd->state);
+                       rc = __qlt_send_busy(qpair, &cmd->atio, cmd->state);
                else if (cmd->term_exchg)
-                       rc = __qlt_send_term_exchange(vha, NULL, &cmd->atio);
+                       rc = __qlt_send_term_exchange(qpair, NULL, &cmd->atio);
 
                if (rc == -ENOMEM)
                        break;
@@ -5177,7 +5303,7 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha)
                /* piggy back on hardware_lock for protection */
                vha->hw->tgt.num_qfull_cmds_alloc--;
        }
-       spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
        cmd = NULL;
 
@@ -5188,23 +5314,31 @@ qlt_free_qfull_cmds(struct scsi_qla_host *vha)
                 */
                qlt_free_cmd(cmd);
        }
+
+       if (!list_empty(&q_full_list)) {
+               spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
+               list_splice(&q_full_list, &vha->hw->tgt.q_full_list);
+               spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
+       }
+
        return rc;
 }
 
 static void
-qlt_send_busy(struct scsi_qla_host *vha,
-       struct atio_from_isp *atio, uint16_t status)
+qlt_send_busy(struct qla_qpair *qpair, struct atio_from_isp *atio,
+    uint16_t status)
 {
        int rc = 0;
+       struct scsi_qla_host *vha = qpair->vha;
 
-       rc = __qlt_send_busy(vha, atio, status);
+       rc = __qlt_send_busy(qpair, atio, status);
        if (rc == -ENOMEM)
                qlt_alloc_qfull_cmd(vha, atio, status, 1);
 }
 
 static int
-qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
-       struct atio_from_isp *atio, bool ha_locked)
+qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
+       struct atio_from_isp *atio, uint8_t ha_locked)
 {
        struct qla_hw_data *ha = vha->hw;
        uint16_t status;
@@ -5216,7 +5350,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
        if (!ha_locked)
                spin_lock_irqsave(&ha->hardware_lock, flags);
        status = temp_sam_status;
-       qlt_send_busy(vha, atio, status);
+       qlt_send_busy(qpair, atio, status);
        if (!ha_locked)
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -5255,16 +5389,17 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                            "sending QUEUE_FULL\n", vha->vp_idx);
                        if (!ha_locked)
                                spin_lock_irqsave(&ha->hardware_lock, flags);
-                       qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL);
+                       qlt_send_busy(ha->base_qpair, atio,
+                           SAM_STAT_TASK_SET_FULL);
                        if (!ha_locked)
-                               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                               spin_unlock_irqrestore(&ha->hardware_lock,
+                                   flags);
                        break;
                }
 
-
-
                if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
-                       rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked);
+                       rc = qlt_chk_qfull_thresh_hold(vha, ha->base_qpair,
+                           atio, ha_locked);
                        if (rc != 0) {
                                tgt->atio_irq_cmd_count--;
                                return;
@@ -5276,19 +5411,19 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                if (unlikely(rc != 0)) {
                        if (rc == -ESRCH) {
                                if (!ha_locked)
-                                       spin_lock_irqsave
-                                               (&ha->hardware_lock, flags);
+                                       spin_lock_irqsave(&ha->hardware_lock,
+                                           flags);
 
 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
-                               qlt_send_busy(vha, atio, SAM_STAT_BUSY);
+                               qlt_send_busy(ha->base_qpair, atio,
+                                   SAM_STAT_BUSY);
 #else
-                               qlt_send_term_exchange(vha, NULL, atio, 1, 0);
+                               qlt_send_term_exchange(ha->base_qpair, NULL,
+                                   atio, 1, 0);
 #endif
-
                                if (!ha_locked)
-                                       spin_unlock_irqrestore
-                                               (&ha->hardware_lock, flags);
-
+                                       spin_unlock_irqrestore(
+                                           &ha->hardware_lock, flags);
                        } else {
                                if (tgt->tgt_stop) {
                                        ql_dbg(ql_dbg_tgt, vha, 0xe059,
@@ -5303,7 +5438,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
                                        if (!ha_locked)
                                                spin_lock_irqsave(
                                                    &ha->hardware_lock, flags);
-                                       qlt_send_busy(vha, atio, SAM_STAT_BUSY);
+                                       qlt_send_busy(ha->base_qpair,
+                                           atio, SAM_STAT_BUSY);
                                        if (!ha_locked)
                                                spin_unlock_irqrestore(
                                                    &ha->hardware_lock, flags);
@@ -5344,7 +5480,8 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
 
 /* ha->hardware_lock supposed to be held on entry */
 /* called via callback from qla2xxx */
-static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
+static void qlt_response_pkt(struct scsi_qla_host *vha,
+       struct rsp_que *rsp, response_t *pkt)
 {
        struct qla_hw_data *ha = vha->hw;
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
@@ -5361,14 +5498,12 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
         * Otherwise, some commands can stuck.
         */
 
-       tgt->irq_cmd_count++;
-
        switch (pkt->entry_type) {
        case CTIO_CRC2:
        case CTIO_TYPE7:
        {
                struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
-               qlt_do_ctio_completion(vha, entry->handle,
+               qlt_do_ctio_completion(vha, rsp, entry->handle,
                    le16_to_cpu(entry->status)|(pkt->entry_status << 16),
                    entry);
                break;
@@ -5387,19 +5522,17 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
                        break;
                }
 
-               rc = qlt_chk_qfull_thresh_hold(vha, atio, true);
-               if (rc != 0) {
-                       tgt->irq_cmd_count--;
+               rc = qlt_chk_qfull_thresh_hold(vha, rsp->qpair, atio, 1);
+               if (rc != 0)
                        return;
-               }
 
                rc = qlt_handle_cmd_for_atio(vha, atio);
                if (unlikely(rc != 0)) {
                        if (rc == -ESRCH) {
 #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
-                               qlt_send_busy(vha, atio, 0);
+                               qlt_send_busy(rsp->qpair, atio, 0);
 #else
-                               qlt_send_term_exchange(vha, NULL, atio, 1, 0);
+                               qlt_send_term_exchange(rsp->qpair, NULL, atio, 1, 0);
 #endif
                        } else {
                                if (tgt->tgt_stop) {
@@ -5407,14 +5540,14 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
                                            "qla_target: Unable to send "
                                            "command to target, sending TERM "
                                            "EXCHANGE for rsp\n");
-                                       qlt_send_term_exchange(vha, NULL,
+                                       qlt_send_term_exchange(rsp->qpair, NULL,
                                            atio, 1, 0);
                                } else {
                                        ql_dbg(ql_dbg_tgt, vha, 0xe060,
                                            "qla_target(%d): Unable to send "
                                            "command to target, sending BUSY "
                                            "status\n", vha->vp_idx);
-                                       qlt_send_busy(vha, atio, 0);
+                                       qlt_send_busy(rsp->qpair, atio, 0);
                                }
                        }
                }
@@ -5424,7 +5557,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
        case CONTINUE_TGT_IO_TYPE:
        {
                struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
-               qlt_do_ctio_completion(vha, entry->handle,
+               qlt_do_ctio_completion(vha, rsp, entry->handle,
                    le16_to_cpu(entry->status)|(pkt->entry_status << 16),
                    entry);
                break;
@@ -5433,7 +5566,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
        case CTIO_A64_TYPE:
        {
                struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt;
-               qlt_do_ctio_completion(vha, entry->handle,
+               qlt_do_ctio_completion(vha, rsp, entry->handle,
                    le16_to_cpu(entry->status)|(pkt->entry_status << 16),
                    entry);
                break;
@@ -5523,7 +5656,6 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
                break;
        }
 
-       tgt->irq_cmd_count--;
 }
 
 /*
@@ -5536,14 +5668,8 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        int login_code;
 
-       if (!ha->tgt.tgt_ops)
-               return;
-
-       if (unlikely(tgt == NULL)) {
-               ql_dbg(ql_dbg_tgt, vha, 0xe03a,
-                   "ASYNC EVENT %#x, but no tgt (ha %p)\n", code, ha);
+       if (!tgt || tgt->tgt_stop || tgt->tgt_stopped)
                return;
-       }
 
        if (((code == MBA_POINT_TO_POINT) || (code == MBA_CHG_IN_CONNECTION)) &&
            IS_QLA2100(ha))
@@ -5553,7 +5679,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
         * Otherwise, some commands can stuck.
         */
 
-       tgt->irq_cmd_count++;
 
        switch (code) {
        case MBA_RESET:                 /* Reset */
@@ -5576,7 +5701,8 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
                    le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
                    le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
                if (tgt->link_reinit_iocb_pending) {
-                       qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb,
+                       qlt_send_notify_ack(ha->base_qpair,
+                           (void *)&tgt->link_reinit_iocb,
                            0, 0, 0, 0, 0, 0);
                        tgt->link_reinit_iocb_pending = 0;
                }
@@ -5595,17 +5721,17 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
                break;
 
        case MBA_REJECTED_FCP_CMD:
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
-                       "qla_target(%d): Async event LS_REJECT occurred "
-                       "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx,
-                       le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
-                       le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf017,
+                   "qla_target(%d): Async event LS_REJECT occurred (m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)",
+                   vha->vp_idx,
+                   le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
+                   le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
 
                if (le16_to_cpu(mailbox[3]) == 1) {
                        /* exchange starvation. */
                        vha->hw->exch_starvation++;
                        if (vha->hw->exch_starvation > 5) {
-                               ql_log(ql_log_warn, vha, 0xffff,
+                               ql_log(ql_log_warn, vha, 0xd03a,
                                    "Exchange starvation-. Resetting RISC\n");
 
                                vha->hw->exch_starvation = 0;
@@ -5641,7 +5767,6 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha,
                break;
        }
 
-       tgt->irq_cmd_count--;
 }
 
 static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
@@ -5705,12 +5830,12 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
        case MODE_DUAL:
                if (newfcport) {
                        if (!IS_IIDMA_CAPABLE(vha->hw) || !vha->hw->flags.gpsc_supported) {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
+                               ql_dbg(ql_dbg_disc, vha, 0x20fe,
                                   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
                                   __func__, __LINE__, fcport->port_name, vha->fcport_count);
                                qla24xx_post_upd_fcport_work(vha, fcport);
                        } else {
-                               ql_dbg(ql_dbg_disc, vha, 0xffff,
+                               ql_dbg(ql_dbg_disc, vha, 0x20ff,
                                   "%s %d %8phC post gpsc fcp_cnt %d\n",
                                   __func__, __LINE__, fcport->port_name, vha->fcport_count);
                                qla24xx_post_gpsc_work(vha, fcport);
@@ -5836,7 +5961,7 @@ static void qlt_abort_work(struct qla_tgt *tgt,
                }
 
                if (!kref_get_unless_zero(&sess->sess_kref)) {
-                       ql_dbg(ql_dbg_tgt_tmr, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01c,
                            "%s: kref_get fail %8phC \n",
                             __func__, sess->port_name);
                        sess = NULL;
@@ -5859,7 +5984,8 @@ out_term2:
 
 out_term:
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false);
+       qlt_24xx_send_abts_resp(ha->base_qpair, &prm->abts,
+           FCP_TMF_REJECTED, false);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
@@ -5873,7 +5999,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
        unsigned long flags;
        uint8_t *s_id = NULL; /* to hide compiler warnings */
        int rc;
-       uint32_t lun, unpacked_lun;
+       u64 unpacked_lun;
        int fn;
        void *iocb;
 
@@ -5900,7 +6026,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
                }
 
                if (!kref_get_unless_zero(&sess->sess_kref)) {
-                       ql_dbg(ql_dbg_tgt_tmr, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_tmr, vha, 0xf020,
                            "%s: kref_get fail %8phC\n",
                             __func__, sess->port_name);
                        sess = NULL;
@@ -5909,9 +6035,9 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
        }
 
        iocb = a;
-       lun = a->u.isp24.fcp_cmnd.lun;
        fn = a->u.isp24.fcp_cmnd.task_mgmt_flags;
-       unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
+       unpacked_lun =
+           scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
 
        rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
        ha->tgt.tgt_ops->put_sess(sess);
@@ -5926,7 +6052,7 @@ out_term2:
                ha->tgt.tgt_ops->put_sess(sess);
        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 out_term:
-       qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0);
+       qlt_send_term_exchange(ha->base_qpair, NULL, &prm->tm_iocb2, 1, 0);
 }
 
 static void qlt_sess_work_fn(struct work_struct *work)
@@ -5974,6 +6100,8 @@ static void qlt_sess_work_fn(struct work_struct *work)
 int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
 {
        struct qla_tgt *tgt;
+       int rc, i;
+       struct qla_qpair_hint *h;
 
        if (!QLA_TGT_MODE_ENABLED())
                return 0;
@@ -5996,9 +6124,47 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
                return -ENOMEM;
        }
 
+       tgt->qphints = kzalloc((ha->max_qpairs + 1) *
+           sizeof(struct qla_qpair_hint), GFP_KERNEL);
+       if (!tgt->qphints) {
+               kfree(tgt);
+               ql_log(ql_log_warn, base_vha, 0x0197,
+                   "Unable to allocate qpair hints.\n");
+               return -ENOMEM;
+       }
+
        if (!(base_vha->host->hostt->supported_mode & MODE_TARGET))
                base_vha->host->hostt->supported_mode |= MODE_TARGET;
 
+       rc = btree_init64(&tgt->lun_qpair_map);
+       if (rc) {
+               kfree(tgt->qphints);
+               kfree(tgt);
+               ql_log(ql_log_info, base_vha, 0x0198,
+                       "Unable to initialize lun_qpair_map btree\n");
+               return -EIO;
+       }
+       h = &tgt->qphints[0];
+       h->qpair = ha->base_qpair;
+       INIT_LIST_HEAD(&h->hint_elem);
+       h->cpuid = ha->base_qpair->cpuid;
+       list_add_tail(&h->hint_elem, &ha->base_qpair->hints_list);
+
+       for (i = 0; i < ha->max_qpairs; i++) {
+               unsigned long flags;
+
+               struct qla_qpair *qpair = ha->queue_pair_map[i];
+               h = &tgt->qphints[i + 1];
+               INIT_LIST_HEAD(&h->hint_elem);
+               if (qpair) {
+                       h->qpair = qpair;
+                       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+                       list_add_tail(&h->hint_elem, &qpair->hints_list);
+                       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+                       h->cpuid = qpair->cpuid;
+               }
+       }
+
        tgt->ha = ha;
        tgt->vha = base_vha;
        init_waitqueue_head(&tgt->waitQ);
@@ -6229,7 +6395,6 @@ qlt_enable_vha(struct scsi_qla_host *vha)
        struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
        unsigned long flags;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
-       int rspq_ent = QLA83XX_RSPQ_MSIX_ENTRY_NUMBER;
 
        if (!tgt) {
                ql_dbg(ql_dbg_tgt, vha, 0xe069,
@@ -6248,17 +6413,6 @@ qlt_enable_vha(struct scsi_qla_host *vha)
                qla24xx_disable_vp(vha);
                qla24xx_enable_vp(vha);
        } else {
-               if (ha->msix_entries) {
-                       ql_dbg(ql_dbg_tgt, vha, 0xffff,
-                           "%s: host%ld : vector %d cpu %d\n",
-                           __func__, vha->host_no,
-                           ha->msix_entries[rspq_ent].vector,
-                           ha->msix_entries[rspq_ent].cpuid);
-
-                       ha->tgt.rspq_vector_cpuid =
-                           ha->msix_entries[rspq_ent].cpuid;
-               }
-
                set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
                qla2xxx_wake_dpc(base_vha);
                qla2x00_wait_for_hba_online(base_vha);
@@ -6385,14 +6539,15 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
                         * can not be trusted. There is no point in passing
                         * it further up.
                         */
-                       ql_log(ql_log_warn, vha, 0xffff,
+                       ql_log(ql_log_warn, vha, 0xd03c,
                            "corrupted fcp frame SID[%3phN] OXID[%04x] EXCG[%x] %64phN\n",
                            pkt->u.isp24.fcp_hdr.s_id,
                            be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id),
                            le32_to_cpu(pkt->u.isp24.exchange_addr), pkt);
 
                        adjust_corrupted_atio(pkt);
-                       qlt_send_term_exchange(vha, NULL, pkt, ha_locked, 0);
+                       qlt_send_term_exchange(ha->base_qpair, NULL, pkt,
+                           ha_locked, 0);
                } else {
                        qlt_24xx_atio_pkt_all_vps(vha,
                            (struct atio_from_isp *)pkt, ha_locked);
@@ -6443,8 +6598,9 @@ void
 qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv)
 {
        struct qla_hw_data *ha = vha->hw;
-       u32 tmp;
-       u16 t;
+
+       if (!QLA_TGT_MODE_ENABLED())
+               return;
 
        if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
                if (!ha->tgt.saved_set) {
@@ -6459,24 +6615,10 @@ qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv)
                        ha->tgt.saved_set = 1;
                }
 
-               if (qla_tgt_mode_enabled(vha)) {
+               if (qla_tgt_mode_enabled(vha))
                        nv->exchange_count = cpu_to_le16(0xFFFF);
-               } else {                        /* dual */
-                       if (ql_dm_tgt_ex_pct > 100) {
-                               ql_dm_tgt_ex_pct = 50;
-                       } else if (ql_dm_tgt_ex_pct == 100) {
-                               /* leave some for FW */
-                               ql_dm_tgt_ex_pct = 95;
-                       }
-
-                       tmp = ha->orig_fw_xcb_count * ql_dm_tgt_ex_pct;
-                       tmp = tmp/100;
-                       if (tmp > 0xffff)
-                               tmp = 0xffff;
-
-                       t = tmp & 0xffff;
-                       nv->exchange_count = cpu_to_le16(t);
-               }
+               else                    /* dual */
+                       nv->exchange_count = cpu_to_le16(ql2xexchoffld);
 
                /* Enable target mode */
                nv->firmware_options_1 |= cpu_to_le32(BIT_4);
@@ -6520,7 +6662,7 @@ qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv)
                return;
        }
 
-       if (ha->tgt.enable_class_2) {
+       if (ha->base_qpair->enable_class_2) {
                if (vha->flags.init_done)
                        fc_host_supported_classes(vha->host) =
                                FC_COS_CLASS2 | FC_COS_CLASS3;
@@ -6561,8 +6703,6 @@ void
 qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
 {
        struct qla_hw_data *ha = vha->hw;
-       u32 tmp;
-       u16 t;
 
        if (!QLA_TGT_MODE_ENABLED())
                return;
@@ -6580,23 +6720,10 @@ qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
                        ha->tgt.saved_set = 1;
                }
 
-               if (qla_tgt_mode_enabled(vha)) {
+               if (qla_tgt_mode_enabled(vha))
                        nv->exchange_count = cpu_to_le16(0xFFFF);
-               } else {                        /* dual */
-                       if (ql_dm_tgt_ex_pct > 100) {
-                               ql_dm_tgt_ex_pct = 50;
-                       } else if (ql_dm_tgt_ex_pct == 100) {
-                               /* leave some for FW */
-                               ql_dm_tgt_ex_pct = 95;
-                       }
-
-                       tmp = ha->orig_fw_xcb_count * ql_dm_tgt_ex_pct;
-                       tmp = tmp/100;
-                       if (tmp > 0xffff)
-                               tmp = 0xffff;
-                       t = tmp & 0xffff;
-                       nv->exchange_count = cpu_to_le16(t);
-               }
+               else                    /* dual */
+                       nv->exchange_count = cpu_to_le16(ql2xexchoffld);
 
                /* Enable target mode */
                nv->firmware_options_1 |= cpu_to_le32(BIT_4);
@@ -6639,7 +6766,7 @@ qlt_81xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_81xx *nv)
                return;
        }
 
-       if (ha->tgt.enable_class_2) {
+       if (ha->base_qpair->enable_class_2) {
                if (vha->flags.init_done)
                        fc_host_supported_classes(vha->host) =
                                FC_COS_CLASS2 | FC_COS_CLASS3;
@@ -6686,21 +6813,6 @@ qlt_83xx_iospace_config(struct qla_hw_data *ha)
        ha->msix_count += 1; /* For ATIO Q */
 }
 
-int
-qlt_24xx_process_response_error(struct scsi_qla_host *vha,
-       struct sts_entry_24xx *pkt)
-{
-       switch (pkt->entry_type) {
-       case ABTS_RECV_24XX:
-       case ABTS_RESP_24XX:
-       case CTIO_TYPE7:
-       case NOTIFY_ACK_TYPE:
-       case CTIO_CRC2:
-               return 1;
-       default:
-               return 0;
-       }
-}
 
 void
 qlt_modify_vp_config(struct scsi_qla_host *vha,
@@ -6742,7 +6854,7 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
 
        rc = btree_init32(&ha->tgt.host_map);
        if (rc)
-               ql_log(ql_log_info, base_vha, 0xffff,
+               ql_log(ql_log_info, base_vha, 0xd03d,
                    "Unable to initialize ha->host_map btree\n");
 
        qlt_update_vp_map(base_vha, SET_VP_IDX);
@@ -6778,7 +6890,8 @@ qlt_handle_abts_recv_work(struct work_struct *work)
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags;
 
-       if (qla2x00_reset_active(vha) || (op->chip_reset != ha->chip_reset))
+       if (qla2x00_reset_active(vha) ||
+           (op->chip_reset != ha->base_qpair->chip_reset))
                return;
 
        spin_lock_irqsave(&ha->tgt.atio_lock, flags);
@@ -6786,14 +6899,15 @@ qlt_handle_abts_recv_work(struct work_struct *work)
        spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       qlt_response_pkt_all_vps(vha, (response_t *)&op->atio);
+       qlt_response_pkt_all_vps(vha, op->rsp, (response_t *)&op->atio);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        kfree(op);
 }
 
 void
-qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt)
+qlt_handle_abts_recv(struct scsi_qla_host *vha, struct rsp_que *rsp,
+    response_t *pkt)
 {
        struct qla_tgt_sess_op *op;
 
@@ -6803,13 +6917,14 @@ qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt)
                /* do not reach for ATIO queue here.  This is best effort err
                 * recovery at this point.
                 */
-               qlt_response_pkt_all_vps(vha, pkt);
+               qlt_response_pkt_all_vps(vha, rsp, pkt);
                return;
        }
 
        memcpy(&op->atio, pkt, sizeof(*pkt));
        op->vha = vha;
-       op->chip_reset = vha->hw->chip_reset;
+       op->chip_reset = vha->hw->base_qpair->chip_reset;
+       op->rsp = rsp;
        INIT_WORK(&op->work, qlt_handle_abts_recv_work);
        queue_work(qla_tgt_wq, &op->work);
        return;
@@ -6870,25 +6985,25 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
        case SET_AL_PA:
                slot = btree_lookup32(&vha->hw->tgt.host_map, key);
                if (!slot) {
-                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+                       ql_dbg(ql_dbg_tgt_mgt, vha, 0xf018,
                            "Save vha in host_map %p %06x\n", vha, key);
                        rc = btree_insert32(&vha->hw->tgt.host_map,
                                key, vha, GFP_ATOMIC);
                        if (rc)
-                               ql_log(ql_log_info, vha, 0xffff,
+                               ql_log(ql_log_info, vha, 0xd03e,
                                    "Unable to insert s_id into host_map: %06x\n",
                                    key);
                        return;
                }
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
-                       "replace existing vha in host_map %p %06x\n", vha, key);
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019,
+                   "replace existing vha in host_map %p %06x\n", vha, key);
                btree_update32(&vha->hw->tgt.host_map, key, vha);
                break;
        case RESET_VP_IDX:
                vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL;
                break;
        case RESET_AL_PA:
-               ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
+               ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a,
                   "clear vha in host_map %p %06x\n", vha, key);
                slot = btree_lookup32(&vha->hw->tgt.host_map, key);
                if (slot)
@@ -6950,7 +7065,7 @@ int __init qlt_init(void)
            sizeof(struct qla_tgt_mgmt_cmd), __alignof__(struct
            qla_tgt_mgmt_cmd), 0, NULL);
        if (!qla_tgt_mgmt_cmd_cachep) {
-               ql_log(ql_log_fatal, NULL, 0xe06d,
+               ql_log(ql_log_fatal, NULL, 0xd04b,
                    "kmem_cache_create for qla_tgt_mgmt_cmd_cachep failed\n");
                return -ENOMEM;
        }