]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/scsi/qla2xxx/qla_isr.c
[SCSI] qla2xxx: Code changes for qla data structure refactoring
[net-next-2.6.git] / drivers / scsi / qla2xxx / qla_isr.c
index fc4bfa7f839c8648e021f643387027d1f67cf1d2..89d327117aa8fc7946542c5337933d8c8a65ddd0 100644 (file)
@@ -14,6 +14,7 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
 static void qla2x00_status_entry(scsi_qla_host_t *, void *);
 static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
+static struct scsi_qla_host *qla2x00_get_rsp_host(struct rsp_que *);
 
 /**
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -27,24 +28,28 @@ static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
 irqreturn_t
 qla2100_intr_handler(int irq, void *dev_id)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *vha;
+       struct qla_hw_data *ha;
        struct device_reg_2xxx __iomem *reg;
        int             status;
        unsigned long   iter;
        uint16_t        hccr;
        uint16_t        mb[4];
+       struct rsp_que *rsp;
 
-       ha = (scsi_qla_host_t *) dev_id;
-       if (!ha) {
+       rsp = (struct rsp_que *) dev_id;
+       if (!rsp) {
                printk(KERN_INFO
-                   "%s(): NULL host pointer\n", __func__);
+                   "%s(): NULL response queue pointer\n", __func__);
                return (IRQ_NONE);
        }
 
+       ha = rsp->hw;
        reg = &ha->iobase->isp;
        status = 0;
 
        spin_lock(&ha->hardware_lock);
+       vha = qla2x00_get_rsp_host(rsp);
        for (iter = 50; iter--; ) {
                hccr = RD_REG_WORD(&reg->hccr);
                if (hccr & HCCR_RISC_PAUSE) {
@@ -59,8 +64,8 @@ qla2100_intr_handler(int irq, void *dev_id)
                        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
                        RD_REG_WORD(&reg->hccr);
 
-                       ha->isp_ops->fw_dump(ha, 1);
-                       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                       ha->isp_ops->fw_dump(vha, 1);
+                       set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                        break;
                } else if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
                        break;
@@ -72,24 +77,24 @@ qla2100_intr_handler(int irq, void *dev_id)
                        /* Get mailbox data. */
                        mb[0] = RD_MAILBOX_REG(ha, reg, 0);
                        if (mb[0] > 0x3fff && mb[0] < 0x8000) {
-                               qla2x00_mbx_completion(ha, mb[0]);
+                               qla2x00_mbx_completion(vha, mb[0]);
                                status |= MBX_INTERRUPT;
                        } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
                                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
                                mb[2] = RD_MAILBOX_REG(ha, reg, 2);
                                mb[3] = RD_MAILBOX_REG(ha, reg, 3);
-                               qla2x00_async_event(ha, mb);
+                               qla2x00_async_event(vha, mb);
                        } else {
                                /*EMPTY*/
                                DEBUG2(printk("scsi(%ld): Unrecognized "
                                    "interrupt type (%d).\n",
-                                   ha->host_no, mb[0]));
+                                   vha->host_no, mb[0]));
                        }
                        /* Release mailbox registers. */
                        WRT_REG_WORD(&reg->semaphore, 0);
                        RD_REG_WORD(&reg->semaphore);
                } else {
-                       qla2x00_process_response_queue(ha);
+                       qla2x00_process_response_queue(vha);
 
                        WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
                        RD_REG_WORD(&reg->hccr);
@@ -118,25 +123,29 @@ qla2100_intr_handler(int irq, void *dev_id)
 irqreturn_t
 qla2300_intr_handler(int irq, void *dev_id)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *vha;
        struct device_reg_2xxx __iomem *reg;
        int             status;
        unsigned long   iter;
        uint32_t        stat;
        uint16_t        hccr;
        uint16_t        mb[4];
+       struct rsp_que *rsp;
+       struct qla_hw_data *ha;
 
-       ha = (scsi_qla_host_t *) dev_id;
-       if (!ha) {
+       rsp = (struct rsp_que *) dev_id;
+       if (!rsp) {
                printk(KERN_INFO
-                   "%s(): NULL host pointer\n", __func__);
+                   "%s(): NULL response queue pointer\n", __func__);
                return (IRQ_NONE);
        }
 
+       ha = rsp->hw;
        reg = &ha->iobase->isp;
        status = 0;
 
        spin_lock(&ha->hardware_lock);
+       vha = qla2x00_get_rsp_host(rsp);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
                if (stat & HSR_RISC_PAUSED) {
@@ -159,8 +168,8 @@ qla2300_intr_handler(int irq, void *dev_id)
                        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
                        RD_REG_WORD(&reg->hccr);
 
-                       ha->isp_ops->fw_dump(ha, 1);
-                       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                       ha->isp_ops->fw_dump(vha, 1);
+                       set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                        break;
                } else if ((stat & HSR_RISC_INT) == 0)
                        break;
@@ -170,7 +179,7 @@ qla2300_intr_handler(int irq, void *dev_id)
                case 0x2:
                case 0x10:
                case 0x11:
-                       qla2x00_mbx_completion(ha, MSW(stat));
+                       qla2x00_mbx_completion(vha, MSW(stat));
                        status |= MBX_INTERRUPT;
 
                        /* Release mailbox registers. */
@@ -181,26 +190,26 @@ qla2300_intr_handler(int irq, void *dev_id)
                        mb[1] = RD_MAILBOX_REG(ha, reg, 1);
                        mb[2] = RD_MAILBOX_REG(ha, reg, 2);
                        mb[3] = RD_MAILBOX_REG(ha, reg, 3);
-                       qla2x00_async_event(ha, mb);
+                       qla2x00_async_event(vha, mb);
                        break;
                case 0x13:
-                       qla2x00_process_response_queue(ha);
+                       qla2x00_process_response_queue(vha);
                        break;
                case 0x15:
                        mb[0] = MBA_CMPLT_1_16BIT;
                        mb[1] = MSW(stat);
-                       qla2x00_async_event(ha, mb);
+                       qla2x00_async_event(vha, mb);
                        break;
                case 0x16:
                        mb[0] = MBA_SCSI_COMPLETION;
                        mb[1] = MSW(stat);
                        mb[2] = RD_MAILBOX_REG(ha, reg, 2);
-                       qla2x00_async_event(ha, mb);
+                       qla2x00_async_event(vha, mb);
                        break;
                default:
                        DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
                            "(%d).\n",
-                           ha->host_no, stat & 0xff));
+                           vha->host_no, stat & 0xff));
                        break;
                }
                WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
@@ -223,10 +232,11 @@ qla2300_intr_handler(int irq, void *dev_id)
  * @mb0: Mailbox0 register
  */
 static void
-qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
+qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
 {
        uint16_t        cnt;
        uint16_t __iomem *wptr;
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        /* Load return mailbox registers. */
@@ -247,10 +257,10 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
 
        if (ha->mcp) {
                DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
-                   __func__, ha->host_no, ha->mcp->mb[0]));
+                   __func__, vha->host_no, ha->mcp->mb[0]));
        } else {
                DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
-                   __func__, ha->host_no));
+                   __func__, vha->host_no));
        }
 }
 
@@ -260,7 +270,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
  * @mb: Mailbox registers (0 - 3)
  */
 void
-qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
+qla2x00_async_event(scsi_qla_host_t *vha, uint16_t *mb)
 {
 #define LS_UNKNOWN     2
        static char     *link_speeds[5] = { "1", "2", "?", "4", "8" };
@@ -268,6 +278,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
        uint16_t        handle_cnt;
        uint16_t        cnt;
        uint32_t        handles[5];
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
        uint32_t        rscn_entry, host_pid;
        uint8_t         rscn_queue_index;
@@ -329,17 +340,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
        switch (mb[0]) {
        case MBA_SCSI_COMPLETION:       /* Fast Post */
-               if (!ha->flags.online)
+               if (!vha->flags.online)
                        break;
 
                for (cnt = 0; cnt < handle_cnt; cnt++)
-                       qla2x00_process_completed_request(ha, handles[cnt]);
+                       qla2x00_process_completed_request(vha, handles[cnt]);
                break;
 
        case MBA_RESET:                 /* Reset */
-               DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
+               DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n",
+                       vha->host_no));
 
-               set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
+               set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
                break;
 
        case MBA_SYSTEM_ERR:            /* System Error */
@@ -347,70 +359,70 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
                    mb[1], mb[2], mb[3]);
 
-               qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
-               ha->isp_ops->fw_dump(ha, 1);
+               qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]);
+               ha->isp_ops->fw_dump(vha, 1);
 
                if (IS_FWI2_CAPABLE(ha)) {
                        if (mb[1] == 0 && mb[2] == 0) {
                                qla_printk(KERN_ERR, ha,
                                    "Unrecoverable Hardware Error: adapter "
                                    "marked OFFLINE!\n");
-                               ha->flags.online = 0;
+                               vha->flags.online = 0;
                        } else
-                               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                } else if (mb[1] == 0) {
                        qla_printk(KERN_INFO, ha,
                            "Unrecoverable Hardware Error: adapter marked "
                            "OFFLINE!\n");
-                       ha->flags.online = 0;
+                       vha->flags.online = 0;
                } else
-                       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                       set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                break;
 
        case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
                DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
 
-               qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+               qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                break;
 
        case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
                DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
 
-               qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+               qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                break;
 
        case MBA_WAKEUP_THRES:          /* Request Queue Wake-up */
                DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
-                   ha->host_no));
+                   vha->host_no));
                break;
 
        case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
-               DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", ha->host_no,
+               DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", vha->host_no,
                    mb[1]));
                qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]);
 
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-                       atomic_set(&ha->loop_state, LOOP_DOWN);
-                       atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
-                       qla2x00_mark_all_devices_lost(ha, 1);
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+                       atomic_set(&vha->loop_state, LOOP_DOWN);
+                       atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
+                       qla2x00_mark_all_devices_lost(vha, 1);
                }
 
-               if (ha->parent) {
-                       atomic_set(&ha->vp_state, VP_FAILED);
-                       fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
+               if (vha->vp_idx) {
+                       atomic_set(&vha->vp_state, VP_FAILED);
+                       fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
                }
 
-               set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
-               set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
+               set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
+               set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
 
-               ha->flags.management_server_logged_in = 0;
-               qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]);
+               vha->flags.management_server_logged_in = 0;
+               qla2x00_post_aen_work(vha, FCH_EVT_LIP, mb[1]);
                break;
 
        case MBA_LOOP_UP:               /* Loop Up Event */
@@ -425,59 +437,59 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                }
 
                DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
-                   ha->host_no, link_speed));
+                   vha->host_no, link_speed));
                qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
                    link_speed);
 
-               ha->flags.management_server_logged_in = 0;
-               qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate);
+               vha->flags.management_server_logged_in = 0;
+               qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate);
                break;
 
        case MBA_LOOP_DOWN:             /* Loop Down Event */
                DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
-                   "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3]));
+                   "(%x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3]));
                qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
                    mb[1], mb[2], mb[3]);
 
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-                       atomic_set(&ha->loop_state, LOOP_DOWN);
-                       atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
-                       ha->device_flags |= DFLG_NO_CABLE;
-                       qla2x00_mark_all_devices_lost(ha, 1);
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+                       atomic_set(&vha->loop_state, LOOP_DOWN);
+                       atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
+                       vha->device_flags |= DFLG_NO_CABLE;
+                       qla2x00_mark_all_devices_lost(vha, 1);
                }
 
-               if (ha->parent) {
-                       atomic_set(&ha->vp_state, VP_FAILED);
-                       fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
+               if (vha->vp_idx) {
+                       atomic_set(&vha->vp_state, VP_FAILED);
+                       fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
                }
 
-               ha->flags.management_server_logged_in = 0;
+               vha->flags.management_server_logged_in = 0;
                ha->link_data_rate = PORT_SPEED_UNKNOWN;
-               qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0);
+               qla2x00_post_aen_work(vha, FCH_EVT_LINKDOWN, 0);
                break;
 
        case MBA_LIP_RESET:             /* LIP reset occurred */
                DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
-                   ha->host_no, mb[1]));
+                   vha->host_no, mb[1]));
                qla_printk(KERN_INFO, ha,
                    "LIP reset occurred (%x).\n", mb[1]);
 
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-                       atomic_set(&ha->loop_state, LOOP_DOWN);
-                       atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
-                       qla2x00_mark_all_devices_lost(ha, 1);
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+                       atomic_set(&vha->loop_state, LOOP_DOWN);
+                       atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
+                       qla2x00_mark_all_devices_lost(vha, 1);
                }
 
-               if (ha->parent) {
-                       atomic_set(&ha->vp_state, VP_FAILED);
-                       fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
+               if (vha->vp_idx) {
+                       atomic_set(&vha->vp_state, VP_FAILED);
+                       fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
                }
 
-               set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
+               set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
 
                ha->operating_mode = LOOP;
-               ha->flags.management_server_logged_in = 0;
-               qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]);
+               vha->flags.management_server_logged_in = 0;
+               qla2x00_post_aen_work(vha, FCH_EVT_LIPRESET, mb[1]);
                break;
 
        case MBA_POINT_TO_POINT:        /* Point-to-Point */
@@ -485,33 +497,33 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                        break;
 
                DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
-                   ha->host_no));
+                   vha->host_no));
 
                /*
                 * Until there's a transition from loop down to loop up, treat
                 * this as loop down only.
                 */
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-                       atomic_set(&ha->loop_state, LOOP_DOWN);
-                       if (!atomic_read(&ha->loop_down_timer))
-                               atomic_set(&ha->loop_down_timer,
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+                       atomic_set(&vha->loop_state, LOOP_DOWN);
+                       if (!atomic_read(&vha->loop_down_timer))
+                               atomic_set(&vha->loop_down_timer,
                                    LOOP_DOWN_TIME);
-                       qla2x00_mark_all_devices_lost(ha, 1);
+                       qla2x00_mark_all_devices_lost(vha, 1);
                }
 
-               if (ha->parent) {
-                       atomic_set(&ha->vp_state, VP_FAILED);
-                       fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
+               if (vha->vp_idx) {
+                       atomic_set(&vha->vp_state, VP_FAILED);
+                       fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
                }
 
-               if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
-                       set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
-               }
-               set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
-               set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
+               if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)))
+                       set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
+
+               set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
+               set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
 
                ha->flags.gpsc_supported = 1;
-               ha->flags.management_server_logged_in = 0;
+               vha->flags.management_server_logged_in = 0;
                break;
 
        case MBA_CHG_IN_CONNECTION:     /* Change in connection mode */
@@ -520,25 +532,25 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
                DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
                    "received.\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_INFO, ha,
                    "Configuration change detected: value=%x.\n", mb[1]);
 
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-                       atomic_set(&ha->loop_state, LOOP_DOWN);
-                       if (!atomic_read(&ha->loop_down_timer))
-                               atomic_set(&ha->loop_down_timer,
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+                       atomic_set(&vha->loop_state, LOOP_DOWN);
+                       if (!atomic_read(&vha->loop_down_timer))
+                               atomic_set(&vha->loop_down_timer,
                                    LOOP_DOWN_TIME);
-                       qla2x00_mark_all_devices_lost(ha, 1);
+                       qla2x00_mark_all_devices_lost(vha, 1);
                }
 
-               if (ha->parent) {
-                       atomic_set(&ha->vp_state, VP_FAILED);
-                       fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
+               if (vha->vp_idx) {
+                       atomic_set(&vha->vp_state, VP_FAILED);
+                       fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
                }
 
-               set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
-               set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
+               set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+               set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                break;
 
        case MBA_PORT_UPDATE:           /* Port database update */
@@ -547,107 +559,106 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                 * event etc. earlier indicating loop is down) then process
                 * it.  Otherwise ignore it and Wait for RSCN to come in.
                 */
-               atomic_set(&ha->loop_down_timer, 0);
-               if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
-                   atomic_read(&ha->loop_state) != LOOP_DEAD) {
+               atomic_set(&vha->loop_down_timer, 0);
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN &&
+                   atomic_read(&vha->loop_state) != LOOP_DEAD) {
                        DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
-                           "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
+                           "ignored %04x/%04x/%04x.\n", vha->host_no, mb[1],
                            mb[2], mb[3]));
                        break;
                }
 
                DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
-                   ha->host_no));
+                   vha->host_no));
                DEBUG(printk(KERN_INFO
                    "scsi(%ld): Port database changed %04x %04x %04x.\n",
-                   ha->host_no, mb[1], mb[2], mb[3]));
+                   vha->host_no, mb[1], mb[2], mb[3]));
 
                /*
                 * Mark all devices as missing so we will login again.
                 */
-               atomic_set(&ha->loop_state, LOOP_UP);
+               atomic_set(&vha->loop_state, LOOP_UP);
 
-               qla2x00_mark_all_devices_lost(ha, 1);
+               qla2x00_mark_all_devices_lost(vha, 1);
 
-               ha->flags.rscn_queue_overflow = 1;
+               vha->flags.rscn_queue_overflow = 1;
 
-               set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
-               set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
+               set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+               set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                break;
 
        case MBA_RSCN_UPDATE:           /* State Change Registration */
                /* Check if the Vport has issued a SCR */
-               if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
+               if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
                        break;
                /* Only handle SCNs for our Vport index. */
-               if (ha->parent && ha->vp_idx != (mb[3] & 0xff))
+               if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff))
                        break;
-
                DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
-                   ha->host_no));
+                   vha->host_no));
                DEBUG(printk(KERN_INFO
                    "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n",
-                   ha->host_no, mb[1], mb[2], mb[3]));
+                   vha->host_no, mb[1], mb[2], mb[3]));
 
                rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
-               host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
-                   ha->d_id.b.al_pa;
+               host_pid = (vha->d_id.b.domain << 16) | (vha->d_id.b.area << 8)
+                               | vha->d_id.b.al_pa;
                if (rscn_entry == host_pid) {
                        DEBUG(printk(KERN_INFO
                            "scsi(%ld): Ignoring RSCN update to local host "
                            "port ID (%06x)\n",
-                           ha->host_no, host_pid));
+                           vha->host_no, host_pid));
                        break;
                }
 
                /* Ignore reserved bits from RSCN-payload. */
                rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
-               rscn_queue_index = ha->rscn_in_ptr + 1;
+               rscn_queue_index = vha->rscn_in_ptr + 1;
                if (rscn_queue_index == MAX_RSCN_COUNT)
                        rscn_queue_index = 0;
-               if (rscn_queue_index != ha->rscn_out_ptr) {
-                       ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
-                       ha->rscn_in_ptr = rscn_queue_index;
+               if (rscn_queue_index != vha->rscn_out_ptr) {
+                       vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry;
+                       vha->rscn_in_ptr = rscn_queue_index;
                } else {
-                       ha->flags.rscn_queue_overflow = 1;
+                       vha->flags.rscn_queue_overflow = 1;
                }
 
-               atomic_set(&ha->loop_state, LOOP_UPDATE);
-               atomic_set(&ha->loop_down_timer, 0);
-               ha->flags.management_server_logged_in = 0;
+               atomic_set(&vha->loop_state, LOOP_UPDATE);
+               atomic_set(&vha->loop_down_timer, 0);
+               vha->flags.management_server_logged_in = 0;
 
-               set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
-               set_bit(RSCN_UPDATE, &ha->dpc_flags);
-               qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry);
+               set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+               set_bit(RSCN_UPDATE, &vha->dpc_flags);
+               qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
                break;
 
        /* case MBA_RIO_RESPONSE: */
        case MBA_ZIO_RESPONSE:
                DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
-                   ha->host_no));
+                   vha->host_no));
                DEBUG(printk(KERN_INFO
                    "scsi(%ld): [R|Z]IO update completion.\n",
-                   ha->host_no));
+                   vha->host_no));
 
                if (IS_FWI2_CAPABLE(ha))
-                       qla24xx_process_response_queue(ha);
+                       qla24xx_process_response_queue(vha);
                else
-                       qla2x00_process_response_queue(ha);
+                       qla2x00_process_response_queue(vha);
                break;
 
        case MBA_DISCARD_RND_FRAME:
                DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
-                   "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
+                   "%04x.\n", vha->host_no, mb[1], mb[2], mb[3]));
                break;
 
        case MBA_TRACE_NOTIFICATION:
                DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
-               ha->host_no, mb[1], mb[2]));
+               vha->host_no, mb[1], mb[2]));
                break;
 
        case MBA_ISP84XX_ALERT:
                DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- "
-                   "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3]));
+                   "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
 
                spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
                switch (mb[1]) {
@@ -682,7 +693,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                break;
        }
 
-       if (!ha->parent && ha->num_vhosts)
+       if (!vha->vp_idx && ha->num_vhosts)
                qla2x00_alert_all_vps(ha, mb);
 }
 
@@ -690,8 +701,8 @@ static void
 qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
 {
        fc_port_t *fcport = data;
-
-       if (fcport->ha->max_q_depth <= sdev->queue_depth)
+       struct qla_hw_data *ha = fcport->vha->hw;
+       if (ha->req->max_q_depth <= sdev->queue_depth)
                return;
 
        if (sdev->ordered_tags)
@@ -703,9 +714,9 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
 
        fcport->last_ramp_up = jiffies;
 
-       DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+       DEBUG2(qla_printk(KERN_INFO, ha,
            "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
-           fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+           fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
            sdev->queue_depth));
 }
 
@@ -717,20 +728,21 @@ qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
        if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
                return;
 
-       DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+       DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
            "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
-           fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+           fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
            sdev->queue_depth));
 }
 
 static inline void
-qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
+qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, srb_t *sp)
 {
        fc_port_t *fcport;
        struct scsi_device *sdev;
+       struct qla_hw_data *ha = vha->hw;
 
        sdev = sp->cmd->device;
-       if (sdev->queue_depth >= ha->max_q_depth)
+       if (sdev->queue_depth >= ha->req->max_q_depth)
                return;
 
        fcport = sp->fcport;
@@ -751,25 +763,27 @@ qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
  * @index: SRB index
  */
 static void
-qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
+qla2x00_process_completed_request(struct scsi_qla_host *vha, uint32_t index)
 {
        srb_t *sp;
+       struct qla_hw_data *ha = vha->hw;
+       struct req_que *req = ha->req;
 
        /* Validate handle. */
        if (index >= MAX_OUTSTANDING_COMMANDS) {
                DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
-                   ha->host_no, index));
+                   vha->host_no, index));
                qla_printk(KERN_WARNING, ha,
                    "Invalid SCSI completion handle %d.\n", index);
 
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                return;
        }
 
-       sp = ha->outstanding_cmds[index];
+       sp = req->outstanding_cmds[index];
        if (sp) {
                /* Free outstanding command slot. */
-               ha->outstanding_cmds[index] = NULL;
+               req->outstanding_cmds[index] = NULL;
 
                CMD_COMPL_STATUS(sp->cmd) = 0L;
                CMD_SCSI_STATUS(sp->cmd) = 0L;
@@ -777,15 +791,15 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
                /* Save ISP completion status */
                sp->cmd->result = DID_OK << 16;
 
-               qla2x00_ramp_up_queue_depth(ha, sp);
-               qla2x00_sp_compl(ha, sp);
+               qla2x00_ramp_up_queue_depth(vha, sp);
+               qla2x00_sp_compl(vha, sp);
        } else {
                DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_WARNING, ha,
                    "Invalid ISP SCSI completion handle\n");
 
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
        }
 }
 
@@ -794,32 +808,34 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
  * @ha: SCSI driver HA context
  */
 void
-qla2x00_process_response_queue(struct scsi_qla_host *ha)
+qla2x00_process_response_queue(struct scsi_qla_host *vha)
 {
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
        sts_entry_t     *pkt;
        uint16_t        handle_cnt;
        uint16_t        cnt;
+       struct rsp_que *rsp = ha->rsp;
 
-       if (!ha->flags.online)
+       if (!vha->flags.online)
                return;
 
-       while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
-               pkt = (sts_entry_t *)ha->response_ring_ptr;
+       while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
+               pkt = (sts_entry_t *)rsp->ring_ptr;
 
-               ha->rsp_ring_index++;
-               if (ha->rsp_ring_index == ha->response_q_length) {
-                       ha->rsp_ring_index = 0;
-                       ha->response_ring_ptr = ha->response_ring;
+               rsp->ring_index++;
+               if (rsp->ring_index == rsp->length) {
+                       rsp->ring_index = 0;
+                       rsp->ring_ptr = rsp->ring;
                } else {
-                       ha->response_ring_ptr++;
+                       rsp->ring_ptr++;
                }
 
                if (pkt->entry_status != 0) {
                        DEBUG3(printk(KERN_INFO
-                           "scsi(%ld): Process error entry.\n", ha->host_no));
+                           "scsi(%ld): Process error entry.\n", vha->host_no));
 
-                       qla2x00_error_entry(ha, pkt);
+                       qla2x00_error_entry(vha, pkt);
                        ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
                        wmb();
                        continue;
@@ -827,31 +843,31 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
 
                switch (pkt->entry_type) {
                case STATUS_TYPE:
-                       qla2x00_status_entry(ha, pkt);
+                       qla2x00_status_entry(vha, pkt);
                        break;
                case STATUS_TYPE_21:
                        handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
                        for (cnt = 0; cnt < handle_cnt; cnt++) {
-                               qla2x00_process_completed_request(ha,
+                               qla2x00_process_completed_request(vha,
                                    ((sts21_entry_t *)pkt)->handle[cnt]);
                        }
                        break;
                case STATUS_TYPE_22:
                        handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
                        for (cnt = 0; cnt < handle_cnt; cnt++) {
-                               qla2x00_process_completed_request(ha,
+                               qla2x00_process_completed_request(vha,
                                    ((sts22_entry_t *)pkt)->handle[cnt]);
                        }
                        break;
                case STATUS_CONT_TYPE:
-                       qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
+                       qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt);
                        break;
                default:
                        /* Type Not Supported. */
                        DEBUG4(printk(KERN_WARNING
                            "scsi(%ld): Received unknown response pkt type %x "
                            "entry status=%x.\n",
-                           ha->host_no, pkt->entry_type, pkt->entry_status));
+                           vha->host_no, pkt->entry_type, pkt->entry_status));
                        break;
                }
                ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
@@ -859,7 +875,7 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
        }
 
        /* Adjust ring index */
-       WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
+       WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index);
 }
 
 static inline void
@@ -881,10 +897,10 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
        sp->request_sense_ptr += sense_len;
        sp->request_sense_length -= sense_len;
        if (sp->request_sense_length != 0)
-               sp->fcport->ha->status_srb = sp;
+               sp->fcport->vha->status_srb = sp;
 
        DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
-           "cmd=%p pid=%ld\n", __func__, sp->fcport->ha->host_no,
+           "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no,
            cp->device->channel, cp->device->id, cp->device->lun, cp,
            cp->serial_number));
        if (sense_len)
@@ -898,7 +914,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
  * @pkt: Entry pointer
  */
 static void
-qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
+qla2x00_status_entry(scsi_qla_host_t *vha, void *pkt)
 {
        srb_t           *sp;
        fc_port_t       *fcport;
@@ -911,6 +927,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        int32_t         resid;
        uint32_t        sense_len, rsp_info_len, resid_len, fw_resid_len;
        uint8_t         *rsp_info, *sense_data;
+       struct qla_hw_data *ha = vha->hw;
+       struct req_que *req = ha->req;
 
        sts = (sts_entry_t *) pkt;
        sts24 = (struct sts_entry_24xx *) pkt;
@@ -924,31 +942,31 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
        /* Fast path completion. */
        if (comp_status == CS_COMPLETE && scsi_status == 0) {
-               qla2x00_process_completed_request(ha, sts->handle);
+               qla2x00_process_completed_request(vha, sts->handle);
 
                return;
        }
 
        /* Validate handle. */
        if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
-               sp = ha->outstanding_cmds[sts->handle];
-               ha->outstanding_cmds[sts->handle] = NULL;
+               sp = req->outstanding_cmds[sts->handle];
+               req->outstanding_cmds[sts->handle] = NULL;
        } else
                sp = NULL;
 
        if (sp == NULL) {
                DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
 
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-               qla2xxx_wake_dpc(ha);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+               qla2xxx_wake_dpc(vha);
                return;
        }
        cp = sp->cmd;
        if (cp == NULL) {
                DEBUG2(printk("scsi(%ld): Command already returned back to OS "
-                   "pkt->handle=%d sp=%p.\n", ha->host_no, sts->handle, sp));
+                   "pkt->handle=%d sp=%p.\n", vha->host_no, sts->handle, sp));
                qla_printk(KERN_WARNING, ha,
                    "Command is NULL: already returned to OS (sp=%p)\n", sp);
 
@@ -987,14 +1005,14 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                if (rsp_info_len > 3 && rsp_info[3]) {
                        DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
                            "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
-                           "retrying command\n", ha->host_no,
+                           "retrying command\n", vha->host_no,
                            cp->device->channel, cp->device->id,
                            cp->device->lun, rsp_info_len, rsp_info[0],
                            rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
                            rsp_info[5], rsp_info[6], rsp_info[7]));
 
                        cp->result = DID_BUS_BUSY << 16;
-                       qla2x00_sp_compl(ha, sp);
+                       qla2x00_sp_compl(vha, sp);
                        return;
                }
        }
@@ -1025,7 +1043,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                                qla_printk(KERN_INFO, ha,
                                           "scsi(%ld:%d:%d:%d): Mid-layer underflow "
                                           "detected (%x of %x bytes)...returning "
-                                          "error status.\n", ha->host_no,
+                                          "error status.\n", vha->host_no,
                                           cp->device->channel, cp->device->id,
                                           cp->device->lun, resid,
                                           scsi_bufflen(cp));
@@ -1039,7 +1057,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
                        DEBUG2(printk(KERN_INFO
                            "scsi(%ld): QUEUE FULL status detected "
-                           "0x%x-0x%x.\n", ha->host_no, comp_status,
+                           "0x%x-0x%x.\n", vha->host_no, comp_status,
                            scsi_status));
 
                        /* Adjust queue depth for all luns on the port. */
@@ -1078,7 +1096,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                        DEBUG2(printk(KERN_INFO
                            "scsi(%ld:%d:%d) UNDERRUN status detected "
                            "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
-                           "os_underflow=0x%x\n", ha->host_no,
+                           "os_underflow=0x%x\n", vha->host_no,
                            cp->device->id, cp->device->lun, comp_status,
                            scsi_status, resid_len, resid, cp->cmnd[0],
                            cp->underflow));
@@ -1095,7 +1113,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                        if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
                                DEBUG2(printk(KERN_INFO
                                    "scsi(%ld): QUEUE FULL status detected "
-                                   "0x%x-0x%x.\n", ha->host_no, comp_status,
+                                   "0x%x-0x%x.\n", vha->host_no, comp_status,
                                    scsi_status));
 
                                /*
@@ -1125,10 +1143,10 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                        if (!(scsi_status & SS_RESIDUAL_UNDER)) {
                                DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
                                              "frame(s) detected (%x of %x bytes)..."
-                                             "retrying command.\n", ha->host_no,
-                                             cp->device->channel, cp->device->id,
-                                             cp->device->lun, resid,
-                                             scsi_bufflen(cp)));
+                                             "retrying command.\n",
+                                       vha->host_no, cp->device->channel,
+                                       cp->device->id, cp->device->lun, resid,
+                                       scsi_bufflen(cp)));
 
                                cp->result = DID_BUS_BUSY << 16;
                                break;
@@ -1140,7 +1158,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                                qla_printk(KERN_INFO, ha,
                                           "scsi(%ld:%d:%d:%d): Mid-layer underflow "
                                           "detected (%x of %x bytes)...returning "
-                                          "error status.\n", ha->host_no,
+                                          "error status.\n", vha->host_no,
                                           cp->device->channel, cp->device->id,
                                           cp->device->lun, resid,
                                           scsi_bufflen(cp));
@@ -1157,7 +1175,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        case CS_DATA_OVERRUN:
                DEBUG2(printk(KERN_INFO
                    "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
-                   ha->host_no, cp->device->id, cp->device->lun, comp_status,
+                   vha->host_no, cp->device->id, cp->device->lun, comp_status,
                    scsi_status));
                DEBUG2(printk(KERN_INFO
                    "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
@@ -1183,19 +1201,24 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                 */
                DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
                    "pid=%ld, compl status=0x%x, port state=0x%x\n",
-                   ha->host_no, cp->device->id, cp->device->lun,
+                   vha->host_no, cp->device->id, cp->device->lun,
                    cp->serial_number, comp_status,
                    atomic_read(&fcport->state)));
 
-               cp->result = DID_BUS_BUSY << 16;
+               /*
+                * We are going to have the fc class block the rport
+                * while we try to recover so instruct the mid layer
+                * to requeue until the class decides how to handle this.
+                */
+               cp->result = DID_TRANSPORT_DISRUPTED << 16;
                if (atomic_read(&fcport->state) == FCS_ONLINE)
-                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
+                       qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
                break;
 
        case CS_RESET:
                DEBUG2(printk(KERN_INFO
                    "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
-                   ha->host_no, comp_status, scsi_status));
+                   vha->host_no, comp_status, scsi_status));
 
                cp->result = DID_RESET << 16;
                break;
@@ -1208,36 +1231,41 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                 */
                DEBUG2(printk(KERN_INFO
                    "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
-                   ha->host_no, comp_status, scsi_status));
+                   vha->host_no, comp_status, scsi_status));
 
                cp->result = DID_RESET << 16;
                break;
 
        case CS_TIMEOUT:
-               cp->result = DID_BUS_BUSY << 16;
+               /*
+                * We are going to have the fc class block the rport
+                * while we try to recover so instruct the mid layer
+                * to requeue until the class decides how to handle this.
+                */
+               cp->result = DID_TRANSPORT_DISRUPTED << 16;
 
                if (IS_FWI2_CAPABLE(ha)) {
                        DEBUG2(printk(KERN_INFO
                            "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
-                           "0x%x-0x%x\n", ha->host_no, cp->device->channel,
+                           "0x%x-0x%x\n", vha->host_no, cp->device->channel,
                            cp->device->id, cp->device->lun, comp_status,
                            scsi_status));
                        break;
                }
                DEBUG2(printk(KERN_INFO
                    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
-                   "sflags=%x.\n", ha->host_no, cp->device->channel,
+                   "sflags=%x.\n", vha->host_no, cp->device->channel,
                    cp->device->id, cp->device->lun, comp_status, scsi_status,
                    le16_to_cpu(sts->status_flags)));
 
                /* Check to see if logout occurred. */
                if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
-                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
+                       qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
                break;
 
        default:
                DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
-                   "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
+                   "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status));
                qla_printk(KERN_INFO, ha,
                    "Unknown status detected 0x%x-0x%x.\n",
                    comp_status, scsi_status);
@@ -1247,8 +1275,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        }
 
        /* Place command on done queue. */
-       if (ha->status_srb == NULL)
-               qla2x00_sp_compl(ha, sp);
+       if (vha->status_srb == NULL)
+               qla2x00_sp_compl(vha, sp);
 }
 
 /**
@@ -1259,10 +1287,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
  * Extended sense data.
  */
 static void
-qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
+qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt)
 {
        uint8_t         sense_sz = 0;
-       srb_t           *sp = ha->status_srb;
+       struct qla_hw_data *ha = vha->hw;
+       srb_t           *sp = vha->status_srb;
        struct scsi_cmnd *cp;
 
        if (sp != NULL && sp->request_sense_length != 0) {
@@ -1274,7 +1303,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
                            "cmd is NULL: already returned to OS (sp=%p)\n",
                            sp);
 
-                       ha->status_srb = NULL;
+                       vha->status_srb = NULL;
                        return;
                }
 
@@ -1295,8 +1324,8 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
 
                /* Place command on done queue. */
                if (sp->request_sense_length == 0) {
-                       ha->status_srb = NULL;
-                       qla2x00_sp_compl(ha, sp);
+                       vha->status_srb = NULL;
+                       qla2x00_sp_compl(vha, sp);
                }
        }
 }
@@ -1307,10 +1336,11 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
  * @pkt: Entry pointer
  */
 static void
-qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
+qla2x00_error_entry(scsi_qla_host_t *vha, sts_entry_t *pkt)
 {
        srb_t *sp;
-
+       struct qla_hw_data *ha = vha->hw;
+       struct req_que *req = ha->req;
 #if defined(QL_DEBUG_LEVEL_2)
        if (pkt->entry_status & RF_INV_E_ORDER)
                qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
@@ -1329,13 +1359,13 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
 
        /* Validate handle. */
        if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
-               sp = ha->outstanding_cmds[pkt->handle];
+               sp = req->outstanding_cmds[pkt->handle];
        else
                sp = NULL;
 
        if (sp) {
                /* Free outstanding command slot. */
-               ha->outstanding_cmds[pkt->handle] = NULL;
+               req->outstanding_cmds[pkt->handle] = NULL;
 
                /* Bad payload or header */
                if (pkt->entry_status &
@@ -1347,17 +1377,17 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                } else {
                        sp->cmd->result = DID_ERROR << 16;
                }
-               qla2x00_sp_compl(ha, sp);
+               qla2x00_sp_compl(vha, sp);
 
        } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
            COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
                DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
-                   ha->host_no));
+                   vha->host_no));
                qla_printk(KERN_WARNING, ha,
                    "Error entry - invalid handle\n");
 
-               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-               qla2xxx_wake_dpc(ha);
+               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+               qla2xxx_wake_dpc(vha);
        }
 }
 
@@ -1367,10 +1397,11 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
  * @mb0: Mailbox0 register
  */
 static void
-qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
+qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
 {
        uint16_t        cnt;
        uint16_t __iomem *wptr;
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
        /* Load return mailbox registers. */
@@ -1385,10 +1416,10 @@ qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
 
        if (ha->mcp) {
                DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
-                   __func__, ha->host_no, ha->mcp->mb[0]));
+                   __func__, vha->host_no, ha->mcp->mb[0]));
        } else {
                DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
-                   __func__, ha->host_no));
+                   __func__, vha->host_no));
        }
 }
 
@@ -1397,30 +1428,32 @@ qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
  * @ha: SCSI driver HA context
  */
 void
-qla24xx_process_response_queue(struct scsi_qla_host *ha)
+qla24xx_process_response_queue(struct scsi_qla_host *vha)
 {
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
        struct sts_entry_24xx *pkt;
+       struct rsp_que *rsp = ha->rsp;
 
-       if (!ha->flags.online)
+       if (!vha->flags.online)
                return;
 
-       while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
-               pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
+       while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
+               pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
 
-               ha->rsp_ring_index++;
-               if (ha->rsp_ring_index == ha->response_q_length) {
-                       ha->rsp_ring_index = 0;
-                       ha->response_ring_ptr = ha->response_ring;
+               rsp->ring_index++;
+               if (rsp->ring_index == rsp->length) {
+                       rsp->ring_index = 0;
+                       rsp->ring_ptr = rsp->ring;
                } else {
-                       ha->response_ring_ptr++;
+                       rsp->ring_ptr++;
                }
 
                if (pkt->entry_status != 0) {
                        DEBUG3(printk(KERN_INFO
-                           "scsi(%ld): Process error entry.\n", ha->host_no));
+                           "scsi(%ld): Process error entry.\n", vha->host_no));
 
-                       qla2x00_error_entry(ha, (sts_entry_t *) pkt);
+                       qla2x00_error_entry(vha, (sts_entry_t *) pkt);
                        ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
                        wmb();
                        continue;
@@ -1428,13 +1461,13 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
 
                switch (pkt->entry_type) {
                case STATUS_TYPE:
-                       qla2x00_status_entry(ha, pkt);
+                       qla2x00_status_entry(vha, pkt);
                        break;
                case STATUS_CONT_TYPE:
-                       qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
+                       qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt);
                        break;
                case VP_RPT_ID_IOCB_TYPE:
-                       qla24xx_report_id_acquisition(ha,
+                       qla24xx_report_id_acquisition(vha,
                            (struct vp_rpt_id_entry_24xx *)pkt);
                        break;
                default:
@@ -1442,7 +1475,7 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
                        DEBUG4(printk(KERN_WARNING
                            "scsi(%ld): Received unknown response pkt type %x "
                            "entry status=%x.\n",
-                           ha->host_no, pkt->entry_type, pkt->entry_status));
+                           vha->host_no, pkt->entry_type, pkt->entry_status));
                        break;
                }
                ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
@@ -1450,14 +1483,15 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
        }
 
        /* Adjust ring index */
-       WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
+       WRT_REG_DWORD(&reg->rsp_q_out, rsp->ring_index);
 }
 
 static void
-qla2xxx_check_risc_status(scsi_qla_host_t *ha)
+qla2xxx_check_risc_status(scsi_qla_host_t *vha)
 {
        int rval;
        uint32_t cnt;
+       struct qla_hw_data *ha = vha->hw;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
        if (!IS_QLA25XX(ha))
@@ -1511,25 +1545,29 @@ done:
 irqreturn_t
 qla24xx_intr_handler(int irq, void *dev_id)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *vha;
+       struct qla_hw_data *ha;
        struct device_reg_24xx __iomem *reg;
        int             status;
        unsigned long   iter;
        uint32_t        stat;
        uint32_t        hccr;
        uint16_t        mb[4];
+       struct rsp_que *rsp;
 
-       ha = (scsi_qla_host_t *) dev_id;
-       if (!ha) {
+       rsp = (struct rsp_que *) dev_id;
+       if (!rsp) {
                printk(KERN_INFO
-                   "%s(): NULL host pointer\n", __func__);
+                   "%s(): NULL response queue pointer\n", __func__);
                return IRQ_NONE;
        }
 
+       ha = rsp->hw;
        reg = &ha->iobase->isp24;
        status = 0;
 
        spin_lock(&ha->hardware_lock);
+       vha = qla2x00_get_rsp_host(rsp);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->host_status);
                if (stat & HSRX_RISC_PAUSED) {
@@ -1537,7 +1575,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
                                break;
 
                        if (ha->hw_event_pause_errors == 0)
-                               qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
+                               qla2x00_post_hwe_work(vha, HW_EVENT_PARITY_ERR,
                                    0, MSW(stat), LSW(stat));
                        else if (ha->hw_event_pause_errors < 0xffffffff)
                                ha->hw_event_pause_errors++;
@@ -1547,10 +1585,10 @@ qla24xx_intr_handler(int irq, void *dev_id)
                        qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
                            "Dumping firmware!\n", hccr);
 
-                       qla2xxx_check_risc_status(ha);
+                       qla2xxx_check_risc_status(vha);
 
-                       ha->isp_ops->fw_dump(ha, 1);
-                       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                       ha->isp_ops->fw_dump(vha, 1);
+                       set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                        break;
                } else if ((stat & HSRX_RISC_INT) == 0)
                        break;
@@ -1560,7 +1598,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
                case 0x2:
                case 0x10:
                case 0x11:
-                       qla24xx_mbx_completion(ha, MSW(stat));
+                       qla24xx_mbx_completion(vha, MSW(stat));
                        status |= MBX_INTERRUPT;
 
                        break;
@@ -1569,15 +1607,15 @@ qla24xx_intr_handler(int irq, void *dev_id)
                        mb[1] = RD_REG_WORD(&reg->mailbox1);
                        mb[2] = RD_REG_WORD(&reg->mailbox2);
                        mb[3] = RD_REG_WORD(&reg->mailbox3);
-                       qla2x00_async_event(ha, mb);
+                       qla2x00_async_event(vha, mb);
                        break;
                case 0x13:
-                       qla24xx_process_response_queue(ha);
+                       qla24xx_process_response_queue(vha);
                        break;
                default:
                        DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
                            "(%d).\n",
-                           ha->host_no, stat & 0xff));
+                           vha->host_no, stat & 0xff));
                        break;
                }
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
@@ -1597,15 +1635,24 @@ qla24xx_intr_handler(int irq, void *dev_id)
 static irqreturn_t
 qla24xx_msix_rsp_q(int irq, void *dev_id)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *vha;
+       struct qla_hw_data *ha;
+       struct rsp_que *rsp;
        struct device_reg_24xx __iomem *reg;
 
-       ha = dev_id;
+       rsp = (struct rsp_que *) dev_id;
+       if (!rsp) {
+               printk(KERN_INFO
+               "%s(): NULL response queue pointer\n", __func__);
+               return IRQ_NONE;
+       }
+       ha = rsp->hw;
        reg = &ha->iobase->isp24;
 
        spin_lock_irq(&ha->hardware_lock);
 
-       qla24xx_process_response_queue(ha);
+       vha = qla2x00_get_rsp_host(rsp);
+       qla24xx_process_response_queue(vha);
        WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 
        spin_unlock_irq(&ha->hardware_lock);
@@ -1616,18 +1663,27 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
 static irqreturn_t
 qla24xx_msix_default(int irq, void *dev_id)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *vha;
+       struct qla_hw_data *ha;
+       struct rsp_que *rsp;
        struct device_reg_24xx __iomem *reg;
        int             status;
        uint32_t        stat;
        uint32_t        hccr;
        uint16_t        mb[4];
 
-       ha = dev_id;
+       rsp = (struct rsp_que *) dev_id;
+       if (!rsp) {
+               DEBUG(printk(
+               "%s(): NULL response queue pointer\n", __func__));
+               return IRQ_NONE;
+       }
+       ha = rsp->hw;
        reg = &ha->iobase->isp24;
        status = 0;
 
        spin_lock_irq(&ha->hardware_lock);
+       vha = qla2x00_get_rsp_host(rsp);
        do {
                stat = RD_REG_DWORD(&reg->host_status);
                if (stat & HSRX_RISC_PAUSED) {
@@ -1635,7 +1691,7 @@ qla24xx_msix_default(int irq, void *dev_id)
                                break;
 
                        if (ha->hw_event_pause_errors == 0)
-                               qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
+                               qla2x00_post_hwe_work(vha, HW_EVENT_PARITY_ERR,
                                    0, MSW(stat), LSW(stat));
                        else if (ha->hw_event_pause_errors < 0xffffffff)
                                ha->hw_event_pause_errors++;
@@ -1645,10 +1701,10 @@ qla24xx_msix_default(int irq, void *dev_id)
                        qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
                            "Dumping firmware!\n", hccr);
 
-                       qla2xxx_check_risc_status(ha);
+                       qla2xxx_check_risc_status(vha);
 
-                       ha->isp_ops->fw_dump(ha, 1);
-                       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                       ha->isp_ops->fw_dump(vha, 1);
+                       set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                        break;
                } else if ((stat & HSRX_RISC_INT) == 0)
                        break;
@@ -1658,7 +1714,7 @@ qla24xx_msix_default(int irq, void *dev_id)
                case 0x2:
                case 0x10:
                case 0x11:
-                       qla24xx_mbx_completion(ha, MSW(stat));
+                       qla24xx_mbx_completion(vha, MSW(stat));
                        status |= MBX_INTERRUPT;
 
                        break;
@@ -1667,15 +1723,15 @@ qla24xx_msix_default(int irq, void *dev_id)
                        mb[1] = RD_REG_WORD(&reg->mailbox1);
                        mb[2] = RD_REG_WORD(&reg->mailbox2);
                        mb[3] = RD_REG_WORD(&reg->mailbox3);
-                       qla2x00_async_event(ha, mb);
+                       qla2x00_async_event(vha, mb);
                        break;
                case 0x13:
-                       qla24xx_process_response_queue(ha);
+                       qla24xx_process_response_queue(vha);
                        break;
                default:
                        DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
                            "(%d).\n",
-                           ha->host_no, stat & 0xff));
+                           vha->host_no, stat & 0xff));
                        break;
                }
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
@@ -1709,23 +1765,25 @@ static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
 };
 
 static void
-qla24xx_disable_msix(scsi_qla_host_t *ha)
+qla24xx_disable_msix(struct qla_hw_data *ha)
 {
        int i;
        struct qla_msix_entry *qentry;
+       struct rsp_que *rsp = ha->rsp;
 
        for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
                qentry = &ha->msix_entries[imsix_entries[i].index];
                if (qentry->have_irq)
-                       free_irq(qentry->msix_vector, ha);
+                       free_irq(qentry->msix_vector, rsp);
        }
        pci_disable_msix(ha->pdev);
 }
 
 static int
-qla24xx_enable_msix(scsi_qla_host_t *ha)
+qla24xx_enable_msix(struct qla_hw_data *ha)
 {
        int i, ret;
+       struct rsp_que *rsp = ha->rsp;
        struct msix_entry entries[QLA_MSIX_ENTRIES];
        struct qla_msix_entry *qentry;
 
@@ -1747,7 +1805,7 @@ qla24xx_enable_msix(scsi_qla_host_t *ha)
                qentry->msix_entry = entries[i].entry;
                qentry->have_irq = 0;
                ret = request_irq(qentry->msix_vector,
-                   imsix_entries[i].handler, 0, imsix_entries[i].name, ha);
+                   imsix_entries[i].handler, 0, imsix_entries[i].name, rsp);
                if (ret) {
                        qla_printk(KERN_WARNING, ha,
                            "MSI-X: Unable to register handler -- %x/%d.\n",
@@ -1763,20 +1821,21 @@ msix_out:
 }
 
 int
-qla2x00_request_irqs(scsi_qla_host_t *ha)
+qla2x00_request_irqs(struct qla_hw_data *ha)
 {
        int ret;
        device_reg_t __iomem *reg = ha->iobase;
+       struct rsp_que *rsp = ha->rsp;
 
        /* If possible, enable MSI-X. */
        if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha))
                goto skip_msix;
 
-        if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
-           !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
+       if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
+               !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
                DEBUG2(qla_printk(KERN_WARNING, ha,
-                   "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
-                   ha->chip_revision, ha->fw_attributes));
+               "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
+                       ha->pdev->revision, ha->fw_attributes));
 
                goto skip_msix;
        }
@@ -1815,7 +1874,7 @@ skip_msix:
 skip_msi:
 
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
-           IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
+           IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
        if (ret) {
                qla_printk(KERN_WARNING, ha,
                    "Failed to reserve interrupt %d already in use.\n",
@@ -1823,10 +1882,8 @@ skip_msi:
                goto fail;
        }
        ha->flags.inta_enabled = 1;
-       ha->host->irq = ha->pdev->irq;
 clear_risc_ints:
 
-       ha->isp_ops->disable_intrs(ha);
        spin_lock_irq(&ha->hardware_lock);
        if (IS_FWI2_CAPABLE(ha)) {
                WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
@@ -1843,13 +1900,35 @@ fail:
 }
 
 void
-qla2x00_free_irqs(scsi_qla_host_t *ha)
+qla2x00_free_irqs(scsi_qla_host_t *vha)
 {
+       struct qla_hw_data *ha = vha->hw;
+       struct rsp_que *rsp = ha->rsp;
 
        if (ha->flags.msix_enabled)
                qla24xx_disable_msix(ha);
        else if (ha->flags.inta_enabled) {
-               free_irq(ha->host->irq, ha);
+               free_irq(ha->pdev->irq, rsp);
                pci_disable_msi(ha->pdev);
        }
 }
+
+static struct scsi_qla_host *
+qla2x00_get_rsp_host(struct rsp_que *rsp)
+{
+       srb_t *sp;
+       struct qla_hw_data *ha = rsp->hw;
+       struct scsi_qla_host *vha = NULL;
+       struct sts_entry_24xx *pkt = (struct sts_entry_24xx *) rsp->ring_ptr;
+
+       if (pkt && pkt->handle < MAX_OUTSTANDING_COMMANDS) {
+               sp = ha->req->outstanding_cmds[pkt->handle];
+               if (sp)
+                       vha = sp->vha;
+       }
+       if (!vha)
+       /* Invalid entry, handle it in base queue */
+               vha = pci_get_drvdata(ha->pdev);
+
+       return vha;
+}